Requests模块是使用Apache2 licensed开源协议的HTTP库。
Requests模块可以非常容易的发送HTTP/1.1请求,无需手动向url添加查询字符串,也不需要对POST数据进行表单编码。由于urllib3,Keep alive和HTTP连接池是自动的。
Requests 完全满足今日 web 的需求。
Requests 支持 Python 2.6—2.7以及3.3—3.7,而且能在 PyPy 下完美运行。
在指定的Python工作区目录下使用终端运行命令:
$ pip install requests
等待安装完成即可。
Requests模块在GutHub上是开源的,可以在公共存储库中clone:
$ git clone git://github.com/psf/requests.git
或者下载压缩包:
$ curl -OL https://github.com/psf/requests/tarball/master
# 也可以选择使用zipball(对于Windows用户)。
拥有源代码的副本后,可以将其嵌入到Python工作区的package中,或将其安装到site-packages中:
$ cd requests
$ pip install .
首先需要导入Requests模块:
import requests
尝试获取某个网页:
r = requests.get('http://www.xxx.com')
print(r)
<Response [200]>
现在有了一个名为r
的Response对象,我们可以从这个对象中获取我们所需要的信息。
Requests简洁的API意味着所有形式的HTTP请求都是显而易见的,例如如何进行HTTP POST
请求:
r = requests.post('http://www.xxx.com', data={'key': 'value'})
其他类型的HTTP请求也是如此:PUT
、DELETE
、HEAD
、OPTIONS
:
r = requests.put('http://www.xxx.com', data={'key': 'value'})
r = requests.delete('http://www.xxx.com')
r = requests.head('http://www.xxx.com')
r = requests.options('http://www.xxx.com')
经常需要在URL请求时添加额外的参数,如果是手工构建URL,那么这些数据将在URL中以?
作为键-值对给出。
例如:http://www.xxx.com?id=1
在Requests模块中允许使用params
关键字参数将这些数据通过字典类型传递:
data = {'key': 'value'}
r = requests.get('http://www.xxx.com', params=data)
可以通过如下方式查看URL已被正确构造:
print(r.url)
http://www.xxx.com?key=value
注
:任何值为None
的字典键都不会添加到URL的查询字符串中。
也可以通过传递列表类型的值:
data = {'key': ['value1', 'value2']}
r = requests.get('http://www.xxx.com', params=data)
print(r.url)
http://www.xxx.com?key=value1&key=value2
可以读取服务器的响应内容:
import requests
r = requests.get('http://www.xxx.com')
r.text
请求将自动解码来自服务器的内容。
当你构建一个请求时,Requests模块会根据HTTP请求头对响应的编码进行有根据的猜测。当使用r.text
时,将使用猜测的文本编码。可以使用如下方法找出Requests模块正使用的编码:
r.encoding
'ISO-8859-1'
r.encoding = 'utf-8'
如果你改变了编码,Requests模块会在之后调用r.text
时使用新的编码。例如,在HTML和XML在主体中指定了编码。
在返回结果中查看到编码为utf-8
合理设置编码可以解决大部分响应乱码问题。
对于非文本请求,也可以使用字节形式访问响应正文:
r.content
gzip和deflate编码转换将自动解码
有内置的JSON解码器,用于处理JSON数据:
r.json()
如果JSON解码失败,r.json()
将引发异常。调用r.json()
的成功并不表示响应成功。有些服务器可能会在失败的响应中返回一个JSON对象(例如HTTP 500
的错误详细信息)。这样的JSON将被解码并返回。
可以使用如下方式检查请求状态码:
r = requests.get('http://www.xxx.com')
r.status_code
200
在极少数情况下,希望从服务器中获取原始响应:
r = requests.get('http://www.xxx.com', stream=True)
r.raw
<urllib3.response.HTTPResponse object at 0x109510d90>
如果要执行此操作,需要在请求中设置:stream=True
如果想向请求添加自定义的HTTP头信息,只需要向headers
参数传入字典类型的数据:
url = 'http://www.xxx.com'
headers = {'user-agent': 'my-app/0.0.1'}
r = requests.get(url, headers=headers)
自定义头信息的优先级低于更具体的信息源,例如:
.netrc
中制定了凭据,则使用headers
参数设置的数据将被重写,后者将被auth
参数重写。此外,Requests不会根据指定的自定义头更改其行为,请求头信息只需传递到最终请求中。
注意:所有请求头的值必须是字符串、字节字符串或unicode。在允许的情况下,建议避免传递unicode类型的值。
通常在发送一些form
表单类型的数据时(比如HTML的表单),只需将字典类型的数据传递给data
参数即可。当请求发出时,字典类型的数据将自动进行表单编码:
data = {'key': 'value'}
r = requests.post('http://www.xxx.com', data=data)
r.text
参数data
也可以为每个键设置多个值,可以传递元祖、列表或以列表作为值的字典完成。当表单中有多个元素使用同一个键时,这样的赋值非常有用:
data_tuples = [('key1', 'value1'), ('key1', 'value2')]
data_dict = {'key1': ['value1', 'value2']}
注
:在希望发送非表单数据时,如果传入一个字符串而非字典时,将直接发送该数据。
您也可以使用json
参数(在版本2.4.2
中添加)直接传递字典类型数据,它将自动编码:
data = {'key': 'value'}
r = requests.post('http://www.xxx.com', json=data)
注
:如果传递了数据或文件,则忽略json
参数。在请求中使用json
参数会将头中的内容类型更改为application/json
。
Requests模块上传多编码文件:
url = 'http://www.xxx.com'
files = {'file': open('report.txt', 'rb')}
r = requests.post(url, files=files)
可以设置文件名、内容类型和头信息
files = {'file': ('report.txt', open('report.txt', 'rb'), 'application/vnd.ms-excel', {'Expires': '0'})}
如果需要可以发送字符串作为文件:
files = {'file': ('report.csv', 'some,data,to,send\nanother,row,to,send\n')}
如果将一个非常大的文件作为表单数据发送请求时,尽可能流式处理。默认情况下并不支持,但有单独的requests-toolbelt
模块可以使用。
要在一个请求中发送多个文件,请参阅高级部分。
注
:强烈建议使用二进制模式打开文件。这是因为Requests模块可能提供内容长度头信息,将该值作为文件中的字节数。如果以文本模式打开文件,则可能出错。
可以检测响应的状态码:
r = requests.get('http://www.xxx.com')
r.status_code
200
Requests附带了一个内置的状态代码检查对象,可以参考:
r.status_code == requests.codes.ok
True
如果是一个错误请求(4XX或者5XX错误响应):
bad_r = requests.get('https://www.xxx.com')
bad_r.status_code
404
bad_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
当响应状态码为200
时,调用raise_for_status()
返回结果为None
:
r.raise_for_status()
None
查看响应头的信息返回格式为Python字典形式:
r.headers
注
:根据RFC 7230,HTTP头信息名称不区分大小写。所以可以使用任意大小写访问请求头信息:
r.headers['Content-Type']
text/html
服务器可以多次发送具有不同值的同一报头,Requests会将他们组合在一起。
如果响应信息中包含一些Cookie信息,可以快速的访问:
r.cookies
可以通过cookies
参数发送给服务器自己构造的Cookies信息:
cookies = dict(UserToken='db0eb5600')
r = requests.get('http://www.xxx.com', cookies=cookies)
Cookies在RequestsCookieJar中返回,它的行为类似于字典,但也提供了一个更完整的接口,适合在多个域或路径上使用。Cookie jar也可以传递给请求:
jar = requests.cookies.RequestsCookieJar()
jar.set('tasty_cookie', 'yum', domain='httpbin.org', path='/cookies')
r = requests.get('http://www.baidu.com', cookies=jar)
默认情况下,请求将对除HEAD之外的所有动词执行位置重定向。
我们可以使用响应对象的history
属性来跟踪重定向。
这个响应历史记录列表包含为完成请求而创建的响应对象。列表将从最早的响应排序到最新的响应。
如果使用GET
、OPTIONS
、POST
、PUT
、PATCH
或DELETE
,则可以使用allow_redirects
参数禁用重定向处理:
r = requests.get('http://xxx.com/', allow_redirects=False)
如果使用HEAD,还可以启用重定向:
r = requests.get('http://xxx.com/', allow_redirects=True)
可以使用timeout
参数告诉Requests模块在给定的秒数后停止等待响应。所有的代码都应该在请求中使用这个参数,否则可能导致程序无限期等待。
requests.get('https://xxx.com/', timeout=1)
注
:参数time
的单位为秒,超时不是整个响应下载的时间限制,如果服务器未发出超时的响应,则会引发异常,如果未显示指定超时,则请求不会超时。
requests.exceptions.ConnectionError
异常。Response.raise_for_status()
将会引发HTTPError
异常。requests.exceptions.ConnectTimeout
异常.TooManyRedirects
异常。requests.exceptions.RequestException
异常。try:
r = requests.get('http://www.xxx.com', timeout=0.001)
except requests.exceptions.ConnectTimeout:
print("Request Timeout")