1 背景

上篇文章讲解了requests模块的基础使用,其中有get、put、post等多种请求方式,使用data、json等格式做为请求参数,在请求体中添加请求头部信息的常见信息,如:headers、cookies,以及对请求响应的处理方法。接下来讲解一下requests的高级用法。

2 进阶方法举例

2.1 requests.request()

method:提交方式(get|post);

url:提交地址;

kwargs:14个控制访问的参数;

常用的参数有:params、data、json、headers、cookies,已在上篇文章中介绍过了,感兴趣的朋友,可以到上篇文章再回顾一下。以下将讲解与示例其他参数的使用。

示例:

2.1.1 files

请求携带文件,如果有的请求需要上传文件,可以用它来实现。

import requests

# 上传文件
f= {"files": open("favicon.ico", "rb") }
data = {"name": "上传文件"} requests.request(
method = 'POST',
url = 'http://127.0.0.1:8080/example/request',
data = data,
files = f
)

需注意:favicon.ico文件需和当前脚本在同一目录下,如果不在,可以将文件名称修改为文件路径

import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth # 1、Basic Auth认证
res = requests.request(
method = 'GET',
url = 'http://127.0.0.1:8080/example/request',
auth = HTTPBasicAuth("username", "password")
)
res.encoding = "gbk" print(res.status) # 200 # 2、DIGEST 认证
res = requests.request(
method = 'GET',
url = 'http://127.0.0.1:8080/example/request',
auth = HTTPDigestAuth("username", "password")
)
res.encoding = "gbk" print(res.status) # 200

http auth认证的两种方式,分别为Basic方式和Digest认证,其中:Basic Auth的优点是提供简单的用户验证功能,其认证过程简单明了,适合于对安全性要求不高的系统或设备中;同样存在缺点:输入的用户名,密码 base64编码后会出现在Authorization里,很容易被解析出来。

那么Digest对比Basic认证有什么不同呢?

  • Digest思想,是使用一种随机数字符串,双方约定好对哪些信息进行哈希运算,即可完成双方身份的验证。Digest模式避免了密码在网络上明文传输,提高了安全性,但它依然存在缺点,例如认证报文被攻击者拦截到攻击者可以获取到资源。
  • DIGEST 认证提供了高于 BASIC 认证的安全等级,但是和 HTTPS 的客户端认证相比仍旧很弱。
  • DIGEST 认证提供防止密码被窃听的保护机制,但并不存在防止用户伪装的保护机制。
  • DIGEST 认证和 BASIC 认证一样,使用上不那么便捷灵活,且仍达不到多数 Web 网站对高度安全等级的追求标准。因此它的适用范围也有所受限。

2.1.2 timeout

请求和响应的超时时间,在网络响应延迟或者无响应时,可以通过设置超时时间,避免等待。

import requests

# 设置请求超时1秒,1秒后无响应,将抛出异常,1秒为connect和read时间总和
requests.request(
method = 'POST',
url = 'http://127.0.0.1:8080/example/request',
json = {'k1' : 'v1', 'k2' : 'v2'},
timeout = 1
) # 分别设置connect和read的超时时间,传入一个数组
requests.request(
method = 'POST',
url = 'http://127.0.0.1:8080/example/request',
json = {'k1' : 'v1', 'k2' : 'v2'},
timeout = (5, 15)
) # 永久等待
requests.request(
method = 'POST',
url = 'http://127.0.0.1:8080/example/request',
json = {'k1' : 'v1', 'k2' : 'v2'},
timeout = None
# 或者删除timeout参数
) # 捕捉超时异常
from requests.exceptions import ReadTimeout
try:
res = requests.get('http://127.0.0.1:8080/example/request', timeout=0.1)
print(res.status_code)
except ReadTimeout:
print("捕捉到超时异常")

2.1.3 allow_redirects

设置重定向开关。

>>> import requests
>>> r = requests.get('http://github.com')
>>> r.url
'https://github.com/' >>> r.status_code
200 >>> r.history
[<Response [301]>] # 如果使用GET、OPTIONS、POST、PUT、PATCH或DELETE,则可以使用allow_redirects参数禁用重定向
>>> r = requests.get('http://github.com', allow_redirects=False) >>> r.status_code
301 >>> r.history
[] # 用HEAD启动重定向
>>> r = requests.head('http://github.com', allow_redirects=True) >>> r.url
'https://github.com/' >>> r.history
[<Response [301]>] import requests
import re # 第一次请求
r1=requests.get('https://github.com/login')
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授权)
authenticity_token=re.findall(r'name="authenticity_token".*?value="(.*?)"',r1.text)[0] #从页面中拿到CSRF TOKEN # 第二次请求:带着初始cookie和TOKEN发送POST请求给登录页面,带上账号密码
data={
'commit':'Sign in',
'utf8':'✓',
'authenticity_token':authenticity_token,
'login':'xxxxxx@qq.com',
'password':'password'
} # 测试一:没有指定allow_redirects=False,则响应头中出现Location就跳转到新页面,
# r2代表新页面的response
r2=requests.post('https://github.com/session',
data=data,
cookies=r1_cookie
) print(r2.status_code) # 200
print(r2.url) # 看到的是跳转后的页面
print(r2.history) # 看到的是跳转前的response
print(r2.history[0].text) # 看到的是跳转前的response.text # 测试二:指定allow_redirects=False,则响应头中即便出现Location也不会跳转到新页面,
# r2代表的仍然是老页面的response
r2=requests.post('https://github.com/session',
data=data,
cookies=r1_cookie,
allow_redirects=False
) print(r2.status_code) # 302
print(r2.url) # 看到的是跳转前的页面https://github.com/session
print(r2.history) # []

2.1.4 proxies

同添加headers方法一样,代理参数是dict。

import requests
import re
def get_html(url):
proxy = {
'http': '120.25.253.234:812',
'https' '163.125.222.244:8123'
}
heads = {}
heads['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'
req = requests.get(url, headers=heads,proxies=proxy)
html = req.text
return html
def get_ipport(html):
regex = r'<td data-title="IP">(.+)</td>'
iplist = re.findall(regex, html)
regex2 = '<td data-title="PORT">(.+)</td>'
portlist = re.findall(regex2, html)
regex3 = r'<td data-title="类型">(.+)</td>'
typelist = re.findall(regex3, html)
sumray = []
for i in iplist:
for p in portlist:
for t in typelist:
pass
pass
a = t+','+i + ':' + p
sumray.append(a)
print('代理')
print(sumray)
if __name__ == '__main__':
url = 'http://www.baidu.com'
get_ipport(get_html(url))

某些接口增加了防骚扰模式,对于大规模且频繁的请求,可能会弹出验证码,或者跳转到登录验证页面,或者封禁IP地址,此时如果想要正常访问,可以通过设置代理来解决这个问题。

除了基本的HTTP代理外,requests还支持SOCKS协议的代理。

# 安装socks库
pip3 install "requests[socks]" # 进行代理
import requests proxies = {
'http': 'socks5://user:password@host:port',
'https': 'socks5://user:password@host:port'
}
res = requests.get('http://www.baidu.com', proxies=proxies)
print(res.status) # 200

2.1.5 hooks

即钩子方法,requests库只支持一个response的钩子,即在响应返回时,可以捎带执行自定义方法。可以用于打印一些信息、做一些响应检查、或者向响应中添加额外的信息。

import requests
url = 'http://www.baidu.com' def verify_res(res, *args, **kwargs):
print('url', res.url)
res.status='PASS' if res.status_code == 200 else 'FAIL' res = requests.get(url, hooks={'response': verify_res})
print(res.text) # <!DOCTYPE html><!--STATUS OK--><html>
print(res.status) # PASS

2.1.6 stream

获取内容立即下载开关,response会将报文一次性全部加载到内存中,如果报文过大,可以使用此参数,迭代下载。

import requests

url="http://www.baidu.com"

r = requests.get(url, stream=True)

# 解析response_body,以\n分割
for lines in r.iter_lines():
print("lines:", lines) # 解析response_body,以字节分割
for chunk in r.iter_content(chunk_size=1024):
print("chunk:", chunk)

2.1.7 verify

认证SSL证书开关,当发送HTTPS请求的时候,如果该网站的证书没有被CA机构信任,程序将报错,可以使用verify参数控制是否检查SSL证书。

# 1、直接设置
import requests response = requests.get('https://www.12306.cn', verify=False)
print(response.status_code) # 2、请求时虽然设置了跳过检查,但是程序运行时仍然会产生警告,警告中包含建议给我们的指定证书
# 可以通过设置,忽略屏蔽这个警告
from requests.packages import urllib3 # 如果报错,则直接引入import urllib3 # 3、屏蔽警告
urllib3.disable_warnings() response = requests.get('https://www.12306.cn', verify=False)
print(response.status_code) # 200 # 4、通过cert直接声明证书
# 本地需要有crt和key文件(key必须是解密状态,加密状态的key是不支持的),并指定它们的路径,
response = requests.get('https://www.12306.cn',cert('/path/server.crt','/path/key'))
print(response.status_code) # 200

2.2 requests库的异常

如何判断是否出现异常呢?

2.2.1 raise_for_status()

该方法在内部判断res.status_code是否等于200,不是则产生异常HTTPError

示例:

# 1、HTTPError异常示例
import requests
from requests.exceptions import HTTPError try:
res = requests.post("http://127.0.0.1:8080/example/post")
res.raise_for_status()
# 等同于
if res.status != 200:
raise HTTPError return res except HTTPError:
return False

2.2.2 ReadTimeout

该异常类型,将会捕捉到因请求/响应超时的请求。

# Timeout超时异常
import requests
from requests.exceptions import ReadTimeout try:
res = requests.get('http://127.0.0.1:8080/example/post',timeout=0.5)
print(res.status_code)
return res except ReadTimeout:
print('timeout')

2.2.3 RequestException

该异常类型,将会捕捉到因无请求引起的异常请求。

# RquestError异常
import requests
from requests.exceptions import RequestException try:
res = requests.get('http://127.0.0.1:8080/example/post')
print(res.status_code)
return res except RequestException:
print('reqerror')

3 总结

看到这里,大家应该明白了,requests库是一个比urilib2模块更加简洁的第三方库,它具有如下的特点:

  • 支持HTTP连接保持和连接池
  • 支持使用cookie、session保持会话
  • 支持文件上传
  • 支持自动响应内容的编码
  • 支持国际化的URL和Post数据自动编码
  • 支持自动实现持久连接keep-alive

因此,requests这个高度封装的模块,可以使我们的HTTP请求,变得更加人性化,使用它将可以轻而易举的完成浏览器请求的任何操作,充分诠释了它的口号:“HTTP for Humans”。

作者:京东物流 骆铜磊

来源:京东云开发者社区

HTTP请求:requests的进阶使用方法浅析的更多相关文章

  1. 网络请求 Requests

    网络请求 Requests url: 就是需要请求,并进行下一步处理的urlcallback: 指定该请求返回的Response,由那个函数来处理.method: 一般不需要指定,使用默认GET方法请 ...

  2. ASP模拟POST请求异步提交数据的方法

    这篇文章主要介绍了ASP模拟POST请求异步提交数据的方法,本文使用MSXML2.SERVERXMLHTTP.3.0实现POST请求,需要的朋友可以参考下 有时需要获取远程网站的某些信息,而服务器又限 ...

  3. C# Winform窗口之间传值的多种方法浅析(转)

    摘要http://www.jb51.net/article/63837.htm 这篇文章主要介绍了C# Winform窗口之间传值的多种方法浅析,本文起讲解了通过构造器传值.通过属性传递.通过事件携带 ...

  4. Ajax设置自定义请求头的两种方法

    用自定义请求头token为例 方法一 $.ajax({ type: "post", url:"http://127.0.0.1:4564/bsky-app/templat ...

  5. Spring MVC 3 表单中文提交post请求和get请求乱码问题的解决方法

    在spring mvc 3.0 框架中,通过JSP页面.HTML页面以POST方式提交表单时,表单的参数传递到对应的servlet后会出现中文显示乱码的问题.解决办法可采用spring自带的过滤技术, ...

  6. AJAX跨域请求json数据的实现方法

    这篇文章介绍了AJAX跨域请求json数据的实现方法,有需要的朋友可以参考一下 我们都知道,AJAX的一大限制是不允许跨域请求. 不过通过使用JSONP来实现.JSONP是一种通过脚本标记注入的方式, ...

  7. file_get_contents无法请求https连接的解决方法 php开启curl

    file_get_contents无法请求https连接的解决方法 方法1: PHP.ini默认配置下,用file_get_contents读取https的链接,就会如下错误: Warning: fo ...

  8. MySQL中同时存在创建和更新时间戳字段解决方法浅析

    MySQL中同时存在创建和更新时间戳字段解决方法浅析 明确我的MySQL版本.mysql> SELECT VERSION();+------------+| VERSION() |+------ ...

  9. React 中的 AJAX 请求:获取数据的方法

    React 中的 AJAX 请求:获取数据的方法 React 只是使用 props 和 state 两处的数据进行组件渲染. 因此,想要使用来自服务端的数据,必须将数据放入组件的 props 或 st ...

  10. SpringMVC的请求转发的三种方法

    SpringMVC请求转发的三种方法 首先明白请求转发是一次请求,地址栏不会发生变化,区别于重定向.springmvc环境自行配置. 以下举例中存在如下文件/WEB-INF/pages/success ...

随机推荐

  1. selenium验证码处理-打码平台操作

    1.进入打码平台(超人,斐斐) 斐斐-------官网: 超人-------官网: 2.选择对应的开发文档,下载对应的demo示例,并把demo的python脚本放到项目包管理地址去 参考: 超人的开 ...

  2. cs 保研经验贴 | 综合面试题库

    绝大部分夏令营都需要面试:如果幸运的话,稍微问几个问题就结束了:不幸的话,可能要抓住你做项目.读论文.复现.做 pre 等等. 这篇博客适用于幸运的情况:绝大部分学校的面试题库,都是彼此重合的,并且一 ...

  3. jmeter分布式测试安装部署步骤

    一.下载linux版本的jdk ----注:下载的jdk和jmeter要与window的jdk和jmeter一致 下载地址:https://www.oracle.com/java/technologi ...

  4. 实现和CSS一样的easing动画?直接看Mozilla、Chromium源码!

    前言 在上一篇丝滑的贝塞尔曲线:从数学原理到应用介绍贝塞尔曲线实现动画时给自己留了一个坑,实现的动画效果和CSS的transition-timing-function: cubic-bezier差别较 ...

  5. [Nginx]安装第三方调试模块——echo | #解决异常#unknown directive “echo”

    前言 echo 模块/指令: 在Nginx中是一个第三方开发者----agentzh(章亦春)开发的.功能强大的调试工具. location = /helloworld/ { default_type ...

  6. Java线程池浅析

    1. 什么是线程池?我们为什么需要线程池? 线程池即可以存放线程的容器,若干个可执行现成在"容器"中等待被调度. 我们都知道,线程的生命周期中有以下状态:新建状态(New).就绪状 ...

  7. 19.13备库duplicate恢复新主库(二)

    问题描述:主备两个库不在同一个机房,此时想从这一套库中在复制一套可读可写的新库出来.网络带宽要求比较高,需要从备库中使用备份在起一个新库,也要测试下使用duplicate从备库能够在复制一个新库.经过 ...

  8. SMT贴片加工钢网工艺制作方法

    smt贴片加工过程中,首先要进行锡膏印刷,而锡膏印刷的工作原理就是用机器刮刀将锡膏推送到钢网的孔洞中,使锡膏与pcb板的电子元器件接触,为下一步焊接做准备.钢网的作用就是与pcb板焊盘位置固定,使锡膏 ...

  9. MySQL(十三)MySQL性能分析工具:慢查询日志与PROFILE查询成本

    性能分析工具SLOW QUERY LOG.PROFILE的使用 ​ 数据库调优的目标就是响应速度更快,吞吐量更大.利用宏观的监控工具和微观的日志分析可以帮助我们找到调优的思路和方式. 数据库调优的步骤 ...

  10. C++ 测试框架 GoogleTest 初学者入门篇 丙

    theme: channing-cyan *以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/RIztusI3uKRno ...