requests 是 Python 中专注于网络请求的一个库,使用起来非常方便。兼容 Python3 以上版本。想要了解更多内容,可以去官方文档地址。
安装和引入
request 扩展安装命令如下:
# 使用 pip 安装
pip install requests
# 使用 easy_install 安装
easy_install requests
在python程序中用 import 导入
import requests
response = requests.get('http://uusama.com')
发送请求
import requests
response = requests.get('http://uusama.com') # get 请求
response = requests.post('http://uusama.com') # post 请求
response = requests.put('http://uusama.com') # put 请求
response = requests.delete('http://uusama.com')# delete 请求
response = requests.head('http://uusama.com') # head 请求
带参数的请求
你可以直接把参数拼接在url后面,也可以通过传入 params 参数实现。另外,传入 data 参数可以将你的参数以表单的形式提交。
data 参数可以是一个字典,元组,字符串。
params = {'key1' : 'value1', 'key2' : 'value2'} # params 参数是一个字符串字典
response = requests.get('http://uusama.com?key1=value1&key2=value2') # 在url中拼接参数
response = requests.get('http://uusama.com', params=params) # 传入 params 参数
data = (('key1', 'value1'), ('key1', 'value2')) # data 参数可以为一个元组,当多个元素使用同一个key时特别有效
response = requests.post('http://uusama.com', data=data) # 传入 data参数
自定义请求头部
通过制定请求时的 headers 参数即可指定HTTP请求的头信息。
如果在 .netrc 中设置了用户认证信息,使用 headers= 设置的授权就不会生效。而如果设置了 auth= 参数,“.netrc“ 的设置就无效了。
如果被重定向到别的主机,授权 header 就会被删除。
代理授权 header 会被 URL 中提供的代理身份覆盖掉。
在我们能判断内容长度的情况下,header 的 Content-Length 会被改写。
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'} # 定义 User-Agent 请求头部
response = requests.get(url, headers=headers)
所有的 header 值必须是 string、bytestring 或者 unicode。尽管传递 unicode header 也是允许的,但不建议这样做。
响应内容
requests 基于 HTTP 头部对响应的编码作出有根据的推测解码,大多数 unicode 字符集都能被无缝地解码
自动为解码 gzip 和 deflate 传输编码的响应数据
通过指定 response.encoding 属性值来设置指定的编码方式,response.text 的值会使用最新的 response.encoding 进行解码
使用 response.content 以字节的方式访问请求响应体,这样可以处理图片等数据
使用 response.json() 可以处理 json 格式返回数据
通过设置请求参数: stream=True,使用 response.raw 可以获取原始套接字响应
response = requests.get('http://uusama.com/wp-content/uploads/2017/07/2017072902480345.jpg')
from PIL import Image
from io import BytesIO
image = Image.open(BytesIO(response.content)) # 使用字节处理图像
response.raw.read(10) # 读取 10 个套接字字符
# 使用 iter_content 来处理流数据
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size):
fd.write(chunk)
响应解析
很多时候,我们不止关注HTTP响应的 body 内容,它的头部信息也很重要
使用 response.status_code 可以获取响应状态码
使用 response.headers 可以查看以字典形式展示的服务器响应头,这个字典大小写不敏感
使用 response.cookie 可以获取响应的 cookie
使用 response.history 可以获取重定向历史, Response 对象的列表,这个对象列表按照从最老到最近的请求进行排序
response = requests.get('http://uusama.com')
response.status_code # 200 获取状态码
response.status_code == requests.codes.ok # True 为方便引用,Requests还附带了一个内置的状态码查询对象
response.raise_for_status() # 当 code 是 4xx 或则 5xx 时,可以使用该方法抛出一个 HTTPError 异常,当为 200 时 抛出为 None
response.headers
# {'content-encoding': 'gzip','transfer-encoding': 'chunked','connection': 'close','server': 'nginx/1.0.4','content-type': 'application/json'}
response.headers.get('content-type')
response.headers['Content-Type']
# 上面两条语句的输出是一样的: 'application/json'
cookies = response.cookies['cookie_name'] # 获取 cookie 中 cookie_name 的值
requests.get(''http://uusama.com', cookies=cookies) # 通过添加请求参数 cookies 传送 cookies
response = requests.get('http:/github.com')
response.history # []
会话对象
会话对象让你能够跨请求保持某些参数。它也会在同一个 Session 实例发出的所有请求之间保持 cookie。任何你传递给请求方法的字典都会与已设置会话层数据合并。方法层的参数覆盖会话的参数。
不过需要注意,就算使用了会话,方法级别的参数也不会被跨请求保持。
s = requests.Session()
s.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get("http://httpbin.org/cookies")
print(r.text)
# '{"cookies": {"sessioncookie": "123456789"}}'
# 会话也可用来为请求方法提供缺省数据。这是通过为会话对象的属性提供数据来实现的:
s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})
# both 'x-test' and 'x-test2' are sent
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
# 面的例子只会和第一个请求发送 cookie ,而非第二个
s = requests.Session()
r = s.get('http://httpbin.org/cookies', cookies={'from-my': 'browser'})
print(r.text)
# '{"cookies": {"from-my": "browser"}}'
r = s.get('http://httpbin.org/cookies')
print(r.text)
# '{"cookies": {}}'
代理
如果需要使用代理,你可以通过为任意请求方法提供 proxies 参数来配置单个请求。
你也可以通过环境变量 HTTP_PROXY 和 HTTPS_PROXY 来配置代理。
若你的代理需要使用HTTP Basic Auth,可以使用 http://user:password@host/ 语法
import requests
proxies = {
"http": "http://10.10.1.10:3128",
"https": "http://10.10.1.10:1080",
}
requests.get("http://example.org", proxies=proxies)
# 命令行
# export HTTP_PROXY="http://10.10.1.10:3128"
# export HTTPS_PROXY="http://10.10.1.10:1080"
# $ python
# http://user:password@host/ 语法
proxies = {
"http": "http://user:pass@10.10.1.10:3128/",
}