咱们可使用Python内置的urllib包来请求网络资源。但它用起来比较麻烦,并且缺乏不少实用的高级功能。本文咱们将会介绍一个更加方便的Python第三方库——Requests的使用。html
要安装Requests
,只要在终端中运行这个简单命令便可:python
pip install -i https://pypi.douban.com/simple requests
安装好Requests
后,就能够开始尝试使用它啦!nginx
使用Requests
发送网络请求很是简单。导入Requests
模块:git
import requests
而后获取某个网页。咱们来获取Github的公共时间线:github
r = requests.get('https://api.github.com/events')
如今,有了一个名为r
的Response
的对象。咱们能够从这个对象中获取全部咱们想要的信息。json
咱们可能会想用URL的查询字符串传递某种数据。若是是手动构建URL,那么数据会以键值对的形式置于URL中,跟在一个问号的后面。例如,http://httpbin.org/get?key=val
。Requests
容许咱们使用params
关键字参数,以一个字符串字典来提供这些参数。举例来讲,若是想传递key1=value1
和key2=value2
到http://httpbin.org/get
,那么可使用以下代码:api
import requests payload = {'name':'viljw', 'cat':'ruby'} r = requests.get('http://httpbin.org/get', params=payload)
打印输出该URL,能看到URL已被正确编码:ruby
print(r.url) # http://httpbin.org/get?name=viljw&cat=ruby
咱们能读取服务器响应内容。举个例子:服务器
import requests r = requests.get("http://httpbin.org/get") print(r.text)
输出内容以下:cookie
Requests
会自动节码来自服务器的内容。大多数unicode字符集都能被无缝地解码。
请求发出后,Requests
会基于HTTP头部对响应的编码做出有根据的推测。当访问r.text
时,Requests
会使用其推测的文本编码。咱们能够找出Requests
使用了什么编码,而且可以使用r.encoding
属性来改变它:
import requests r = requests.get("http://httpbin.org/get") print(r.encoding) r.encoding = 'utf-8' print(r.encoding)
若是改变了编码,每当访问r.text
,Requests
都将会使用r.encoding
的新值。
对于非文本请求,也能以字节的方式访问请求响应体。例如,以请求返回的二进制数据建立一张图片,可使用以下代码:
import requests from PIL import Image from io import BytesIO r = requests.get("https://github.com/fluidicon.png") im = Image.open(BytesIO(r.content)) im.show()
Requests
中有一个内置的JSON解码器,帮助咱们处理JSON数据:
import requests from pprint import pprint payload = {'name':"viljw", 'cat':'ruby'} r = requests.get("http://httpbin.org/get", params=payload) pprint(r.json())
若是想为请求添加HTTP头部,只要简单地传递一个dict
给headers
参数就可。
import requests from pprint import pprint headers = {'User-Agent': 'viljw-agent'} r = requests.get("http://httpbin.org/get", headers=headers) pprint(r.json())
以下图所示,User-Agent
字段的值已被更改成viljw-agent
。
一般,咱们会想要发送一些编码为表单形式的数据——很是像一个HTML表单。要实现这个,只须要简单地传递一个字典给data
参数。字典数据在发出请求时会自动编码为表单形式:
import requests payload = {"name":"viljw", "actor":"peter"} r = requests.post("http://httpbin.org/post", data=payload) print(r.text)
还能够给data
参数传入一个元组列表。在表单中多个元素使用同一key的时候,这种方式颇有用:
import requests payload = [("name","viljw"), ("actor","peter"),("actor",'marry')] r = requests.post("http://httpbin.org/post", data=payload) print(r.text)
咱们能够查看响应状态码:
import requests r = requests.get("http://httpbin.org/get") print(r.status_code) # 200
为了方便使用,Requests
附带了也给内置的状态码查询对象:
r.status_code == requests.codes.ok # True
若是发送了一个错误请求(一个4XX客户端错误,或5XX服务器错误响应),咱们能够经过Response.raise_for_status()
来抛出异常:
In [1]: import requests In [2]: bad_r = requests.get('http://httpbin.org/status/404') In [3]: bad_r.status_code Out[3]: 404 In [4]: bad_r.raise_for_status() --------------------------------------------------------------------------- HTTPError Traceback (most recent call last) <ipython-input-4-cdf6910f7d4c> in <module>() ----> 1 bad_r.raise_for_status() c:\python\lib\site-packages\requests\models.py in raise_for_status(self) 927 928 if http_error_msg: --> 929 raise HTTPError(http_error_msg, response=self) 930 931 def close(self): HTTPError: 404 Client Error: NOT FOUND for url: http://httpbin.org/status/404
但因为咱们的例子中r
的status_code
是200,当咱们调用raise_for_status()
时,获得的是:
In [6]: r.raise_for_status() # None
咱们能够查看以字典形式的服务器响应头:
In [7]: r.headers Out[7]: {'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Content-Encoding': 'gzip', 'Content-Type': 'application/json', 'Date': 'Thu, 03 Oct 2019 07:11:16 GMT', 'Referrer-Policy': 'no-referrer-when-downgrade', 'Server': 'nginx', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'DENY', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '184', 'Connection': 'keep-alive'}
若是某个响应中包含一些cookie,能够快速访问它们:
In [19]: r = requests.get('https://www.baidu.com') In [20]: r.cookies Out[20]: <RequestsCookieJar[Cookie(version=0, name='BDORZ', value='27315', port=None, port_specified=False, domain='.baidu.com', domain_specified=True, domain_initial_dot=True, path='/', path_specified=True, secure=False, expires=1570173564, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False)]> In [21]: r.cookies['BDORZ'] Out[21]: '27315'
要想发送cookies到服务器,可使用cookies
参数:
In [27]: url = 'http://httpbin.org/cookies' In [28]: cookies = dict(cookies_are="working") In [29]: r = requests.get(url, cookies=cookies) In [30]: r.json() Out[30]: {'cookies': {'cookies_are': 'working'}}
能够告诉Requests
在通过以timeout
参数设定的秒数时间以后中止等待响应。
>>> requests.get('http://github.com', timeout=0.001) Traceback (most recent call last): File "<stdin>", line 1, in <module> requests.exceptions.Timeout: HTTPConnectionPool(host='github.com', port=80): Request timed out. (timeout=0.001)
遇到网络问题(如:DNS查询失败、拒绝链接等)时,Requests
会抛出一个ConnectionError
异常。
若是HTTP请求返回了不成功的状态码, Response.raise_for_status()
会抛出一个HTTPError
异常。
若请求超时,则抛出一个Timeout
异常。
若请求超过了设定的最大重定向次数,则会抛出一个TooManyRedirects
异常。
全部Requests
显式抛出的异常都继承自 requests.exceptions.RequestException
。
若是须要使用代理,能够经过任意请求方法提供proxies
参数来配置单个请求:
import requests proxies = { 'https': 'https://127.0.0.1:1080' } r = requests.get('https://www.google.com', proxies=proxies) print(r.status_code) # 200
也能够经过环境变量HTTP_PROXY
和HTTPS_PROXY
来配置代理。
$ 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")