python第三方库requests
Whisper Lv5

请求

传参

通过关键字params传递参数

1
2
3
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('http://httpbin.org/get', params=payload)
#编码成:http://httpbin.org/get?key2=value2&key1=value1

key的value为null时,不会将该组值编码为参数。
list传参:

1
2
3
payload = {'key1': 'value1', 'key2': ['value2', 'value3']}
r = requests.get('http://httpbin.org/get', params=payload)
#编码成:http://httpbin.org/get?key1=value1&key2=value2&key2=value3

设置cookies

1
2
3
4
5
6
>>> url = 'http://httpbin.org/cookies'
>>> cookies = dict(cookies_are='working')

>>> r = requests.get(url, cookies=cookies)
>>> r.text
'{"cookies": {"cookies_are": "working"}}'

更新cookies

1
2
3
4
5
6
7
8
9
s = requests.session()
data = {
'aa': "user"
}
res = s.post(self.login_url, json=data)
print(s.cookies.get_dict())
print("before:", s.cookies)
s.cookies.set('_cookie', 'cxxxxxxxxx', domain="api.xxx.org")
print("after", s.cookies)

输出

1
2
before: <RequestsCookieJar[<Cookie _cookie=4ZJXH0#342712b2344c11ea932d320b79554096 for api.xxx.org/>]>
after <RequestsCookieJar[<Cookie _cookie=cxxxxxxxxx for api.xxx.org/>]>

自定义Header

添加HTTP header,传递一个dict到header的参数中。
例子:设置user-agent

1
2
3
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)

通过自定义的header比其他专门指定的信息的优先级低。

7种请求方法

所有的请求的功能可以由这7方法访问

1
2
3
4
5
6
7
r = requests.request(method, url, **kwargs)
r = requests.head(url, **kwargs)
r = requests.get(url, params=None, **kwargs)
r = requests.post(url, data=None, json=None, **kwargs)
r = requests.put(url, data=None, **kwargs)[source]
r = requests.patch(url, data=None, **kwargs)
r = requests.delete(url, **kwargs)

这七个方法都会返回一个Response对象的一个实例:我们可以从这个对象中获得我们需要的所有信息。

POST

post form表单

参数传一个字典,会自动被编码为form

1
2
3
4
5
6
7
8
9
10
11
12
payload = {'key1': 'value1', 'key2': 'value2'}

r = requests.post("http://httpbin.org/post", data=payload)
print(r.text)
#{
# ...
# "form": {
# "key2": "value2",
# "key1": "value1"
# },
# ...
#}

如果你传递一个string,则不会编译成form。

1
2
3
4
5
6
import json

url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}

r = requests.post(url, data=json.dumps(payload))

或者直接传json

1
2
3
4
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}

r = requests.post(url, json=payload)

post文件

1
2
3
4
5
6
7
8
9
10
11
12
13
 url = 'http://httpbin.org/post'
files = {'file': open('report.xls', 'rb')}

r = requests.post(url, files=files)

# r.text
#{
#...
# "files": {
# "file": "<censored...binary...data>"
# },
# ...
#}

也可以设置文件名称,content_type,headers

1
2
3
4
5
6
7
8
9
10
11
12
13
 url = 'http://httpbin.org/post'
files = {'file': ('report.xls', open('report.xls', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}

r = requests.post(url, files=files)

# r.text
#{
#...
# "files": {
# "file": "<censored...binary...data>"
# },
# ...
#}

发送字符串作为文件:

1
2
3
4
5
>>> url = 'http://httpbin.org/post'
>>> files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}

>>> r = requests.post(url, files=files)
>>> r.text

发送大文件:requests-toolbelt

建议以二进制模式打开文件.

同时传data参数和file图片

1
2
3
f = {'image': ('xxx.jpg', open('xxx.jpg', 'rb')) }
data = {"logo":"logoing","id":某个id}
s.post(url,data = data, files = f)

requests.Session

该类提供cookie持久性、连接池和配置

1
2
3
import requests
s = requests.Session()
s.get('http://httpbin.org/get')

响应

状态码

1
r.status_code

检查请求是否成功

使用r.raise_for_status()或者检查r.status_code是否符合预期。

1
r.status_code == requests.codes.ok

抛出4XX/5XX问题码,200的时候调用会返回None

1
2
3
4
5
r.raise_for_status()
Traceback (most recent call last):
File "requests/models.py", line 832, in raise_for_status
raise http_error
requests.exceptions.HTTPError: 404 Client Error

Headers

1
r.headers

返回的是一个json,可以获得json里面的数据。

cookies

如果响应数据中有cookies,可以获得他们

1
r.cookies['example_cookie_name']

编码

request能自动对响应的内容解码,稍后根据需要的内容编码。
查看编码:r.encoding,也可以修改该编码r.encoding = xxx
HTTP和XML能在body中指定编码,可以通过r.content找到编码,然后通过r.encoding设置。然后r.text就能通过正确的编码显示。

text 编码

1
r.text

二进制编码

1
r.content

gzip deflate 也能成功编码
如:通过返回的二进制数据创建图像

1
2
3
4
from PIL import Image
from StringIO import StringIO

i = Image.open(StringIO(r.content))

内置json解码器

1
r.json

如果解析失败,则会抛出异常ValueError: No JSON object could be decoded
注意:r.json调用成功,并不能表示响应成功。一些服务器会将失败信息使用json返回。检查请求是否成功,使用r.raise_for_status()或者检查r.status_code是否符合预期。

原始套接字

在一些稀少的情况下,也需要拿到原始套接字,使用r.raw获得。首先得在requests的时候,设置stream=True

1
2
3
r = requests.get('https://api.github.com/events', stream=True)
r.raw.read(10)
# '\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x03'

保存流到文件:

1
2
3
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size):
fd.write(chunk)

下载的时候使用最佳。

history

1
r.history

设置请求超时

1
requests.get('http://github.com', timeout=0.001)

超出请求会抛出错误。

错误

所有异常继承 requests.exceptions.RequestException.

  • DNS错误,连接错误等,Requests 会抛出一个ConnectionError 异常
  • 当响应码不符合预期,Response.raise_for_status()抛出HTTPError 异常
  • 请求超时,会抛出Timeout 异常
  • 请求超出配置最大的重定向数,抛出TooManyRedirects 异常

报错:requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]
请求中加上verify=False

1
s.post(url_2, json=data, verify=False)

API文档