requests高级用法
会话对象
当你向同一主机发送多个请求时,session会重用底层的tcp连接,从而提升性能,同时session也会为所有请求保持 cookie。
#!/usr/bin/env python # -*- coding:utf-8 -*- # __author__:kzg import requests s = requests.Session() # 此地址cookie为空 r = s.get('http://httpbin.org/cookies') print(r.text) 结果: { "cookies": {} }
session可以保持cookie来访问后续同一服务器上的地址
#!/usr/bin/env python # -*- coding:utf-8 -*- # __author__:kzg import requests s = requests.Session() r = s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') print(r.text) # cookie被保持来访问此url rc = s.get('http://httpbin.org/cookies') print(rc.text) 结果: { "cookies": { "sessioncookie": "123456789" } } { "cookies": { "sessioncookie": "123456789" } }
可以修改session的属性(cookies,headers)来为请求方法(get,post)提供缺省数据,可保跨请求保持。
# -*- coding:utf-8 -*- # __author__:kzg import requests # 生成session对象 s = requests.Session() print(s.headers) # 修改session属性 s.headers.update({'User-Agent':'kong'}) print(s.headers) r = s.get('http://httpbin.org/headers') print(r.text) 结果: {'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'python-requests/2.18.1'} {'Connection': 'keep-alive', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'User-Agent': 'kong'} { "headers": { "Accept": "*/*", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Host": "httpbin.org", "User-Agent": "kong" } }
也可以通过传递方法层的参数来提供缺省数据,它会与已设置的会话层数据合并,不能跨请求保持。
# -*- coding:utf-8 -*-
# __author__:kzg
import requests
# 生成session对象
s = requests.Session()
# 修改session属性
s.headers.update({'User-Agent':'kong'})
# 方法级参数cookies
r = s.get('http://httpbin.org/headers',cookies={'from-my': 'browser'})
print(r.text)
# 方法级参数不能被保持到下一个请求
r1 = s.get('http://httpbin.org/headers')
print(r1.text)
结果:
{
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Cookie": "from-my=browser",
"Host": "httpbin.org",
"User-Agent": "kong"
}
}
{
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "kong"
}
}
请求与响应对象
你任何时间调用requests.*()的时候,都是在做两件重要的事情。
1、你在构建request对象,并把它发送到某服务器去请求或查询一些资源
2、产生response对象来接收从服务器返回的所有响应,也包含你创建的request对象
# _*_ coding: utf-8 _*_ import requests # 生成一个会话对象 s = requests.Session() r = requests.get('http://en.wikipedia.org/wiki/Monty_Python') # 服务器返回来的头部信息 print r.headers # 发送给服务器的头部信息 print r.request.headers
工作流响应体内容
如果你在请求中使用了stream=True:
1、仅有响应体会被立即下载,只有当访问response.content属性时响应体才会被下载
2、此时连接保持打开状态,需要调用response.close来关闭连接
3、连接效率低下
# _*_ coding: utf-8 _*_ import requests tarball_url = 'https://github.com/kennethreitz/requests/tarball/master' r = requests.get(tarball_url, stream=True) print r.headers['content-length']
结果:
3336071
文件上传
#!/usr/bin/python3 # -*- coding: utf-8 -*- import requests url = 'http://httpbin.org/post' files = {'file': open('D:\\projects\\blog\\my_temp.xlsx', 'rb')} ret = requests.post(url, files=files) print(ret.text)
设置文件名、文件类型和请求头
#!/usr/bin/python3 # -*- coding: utf-8 -*- import requests url = 'http://httpbin.org/post' files = {'file': ('my_temp.xlsx',open('D:\\projects\\blog\\my_temp.xlsx', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})} ret = requests.post(url, files=files) print(ret.text)
流式上传
允许你在请求中发送大的数据流或文件,此时requests会根据文件大小来设置headers中的content-length,所以文件最好以二进制方式打开
with open('massive-body','rb') as f: requests.post('http://some.url/streamed', data=f)
为请求设置代理
如果需要为请求设置代理,只需要给相应的请求提供proxies参数即可。
方法一、
$ export HTTP_PROXY="http://10.10.1.10:3128" $ export HTTPS_PROXY="http://10.10.1.10:1080"
$ python >>> import requests >>> requests.get("http://example.org")
方法二、
# _*_ coding: utf-8 _*_ import requests proxies={ "http":"http://10.10.1.10:3128", "https":"http://10.10.1.10:1080", } r = requests.get("http://example.org",proxies=proxies)
超时
为防止服务器不能及时响应,大部分发至外部服务器的请求都应该带着 timeout 参数
# _*_ coding: utf-8 _*_ import requests # 同时设置connect,read的timeout r = requests.get('https://github.com', timeout=5) # 分别设置connect和read的timeout r = requests.get('https://github.com', timeout=(3.05, 27)) # 永久等待,直到读完 r = requests.get('https://github.com', timeout=None)