Requests 唯一的一个非转基因的 Python HTTP 库,人类可以安全享用。
Requests 允许你发送纯天然,植物饲养的 HTTP/1.1 请求,无需手工劳动。你不需要手动为 URL 添加查询字串,也不需要对 POST 数据进行表单编码。Keep-alive 和 HTTP 连接池的功能是 100% 自动化的,一切动力都来自于根植在 Requests 内部的 urllib3。 ——来自官方文档
我主要参考官方文档,所以先把官方文档贴出来:
1. 安装Requests库
既然是Python的库,那么就可以通过 pip 来进行安装。运行以下指令:
pip install requests
即可安装Requests库。
如果你没有且不愿意安装pip的话,可以去这里 来找到安装方法。(使用pip不好吗)
2. Requests库的基本请求
Requests库中提供了所有的HTTP请求方式,如:
r = requests.get("http://httpbin.org/get")
r = requests.post("http://httpbin.org/post")
r = requests.put("http://httpbin.org/put")
r = requests.delete("http://httpbin.org/delete")
r = requests.head("http://httpbin.org/get")
r = requests.options("http://httpbin.org/get")
2.1 引例
下面是一个小例子:
import requests
r = requests.get('https://blog.domineto.top')
print (type(r))
print (r.status_code)
print (r.encoding)
print (r.text)
print (r.cookies)
以上代码我们请求了本站点的网址,然后打印出了返回结果的类型,状态码,编码方式,Cookies等内容。
<class 'requests.models.Response'>
200
UTF-8
//因为text太长了所以后面两个就不写出来了
2.2 基本GET请求
GET请求是我们GET请求是我们最常用的方式。我们通过URL获得 web application 中的信息就是GET方式获取的。
Requests库中进行GET请求也是很方便的:
r = requests.get("http://httpbin.org/get")
这样,我们有一个名为 r 的 Response 对象。我们可以从这个对象中获取所有我们想要的信息。
传递URL参数
我们在访问王我们在访问网站的时候,经常会需要传递一些参数。如果我们是手工构建 URL,那么数据会以键/值对的形式置于 URL 中,跟在一个问号的后面。例如: httpbin.org/get?key=val
。
在Requests中,我们可以使用 params 关键字参数,以一个字符串字典来提供这些参数。
举例如下:
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.get("http://httpbin.org/get", params=payload)
print (r.url)
http://httpbin.org/get?key2=value2&key1=value1
可以看到,我们传递的参数已经被正确地编码了。
添加Header
如果想添加 headers,可以传 headers 参数:
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
headers = {'content-type': 'application/json'}
r = requests.get("http://httpbin.org/get", params=payload, headers=headers)
print r.url
通过headers参数可以增加请求头中的headers信息
2.3 基本POST请求
对于 POST 请求来说,我们一般需要为它增加一些参数。那么最基本的传参方法可以利用 data 这个参数。
一般的表单数据
import requests
payload = {'key1': 'value1', 'key2': 'value2'}
r = requests.post("http://httpbin.org/post", data=payload)
print (r.text)
{
"args": {},
"data": "",
"files": {},
"form": {
"key1": "value1",
"key2": "value2"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "23",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.21.0"
},
"json": null,
"origin": "218.17.40.219, 218.17.40.219",
"url": "https://httpbin.org/post"
}
由此可见我们成功把参数POST上去了。
JSON数据
有时候我们需要传送的信息不是表单形式的,需要我们传JSON格式的数据过去,所以我们可以用 json.dumps()
方法把表单数据序列化。
import json
import requests
url = 'http://httpbin.org/post'
payload = {'some': 'data'}
r = requests.post(url, data=json.dumps(payload))
print (r.text)
{
"args": {},
"data": "{\"some\": \"data\"}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "16",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.9.1"
},
"json": {
"some": "data"
},
"url": "http://httpbin.org/post"
}
通过上述方法,我们可以POST JSON格式的数据
文件
如果想要上传文件,那么我们可以直接使用 file 参数即可。
首先我们先新建一个 text.txt 的文件,内容写上 “Hello World!”,作为要上传的文件。
import requests
url = 'http://httpbin.org/post'
files = {'file': open('test.txt', 'rb')}
r = requests.post(url, files=files)
print (r.text)
{
"args": {},
"data": "",
"files": {
"file": "Hello World!"
},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "156",
"Content-Type": "multipart/form-data; boundary=7d8eb5ff99a04c11bb3e862ce78d7000",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.9.1"
},
"json": null,
"url": "http://httpbin.org/post"
}
这样我们便成功完成了一个文件的上传。
3. 响应内容
3.1 一般响应内容
我们在获得了一个 response 对象后,可以读取响应的内容。以 GitHub 时间线为例:
import requests
r = requests.get('https://api.github.com/events')
r.text
Requests 会自动解码来自服务器的内容。大多数 unicode 字符集都能被无缝地解码。
请求发出后,Requests 会基于 HTTP 头部对响应的编码作出有根据的推测。当我们访问 r.text 之时,Requests 会使用其推测的文本编码。我们可以找出 Requests 使用了什么编码,并且能够使用 r.encoding 属性来改变它:
r.encoding
#结果:'utf-8'
r.encoding = 'ISO-8859-1'
如果我们改变了编码,每当我们访问 r.text ,Request 都将会使用 r.encoding 的新值。
3.2 二进制响应内容
如果想以字节的方式访问请求响应体,我们可以使用 r.content
来实现。Requests 会自动解码 gzip 和 deflate 传输编码的响应数据。
3.3 JSON响应内容
Requests库中内置了一个JSON解码器,可以让我们处理JSON数据:
import requests
r = requests.get('https://api.github.com/events')
r.json()
如果 JSON 解码失败, r.json()
就会抛出一个异常。例如,响应内容是 401 (Unauthorized)
,尝试访问 r.json()
将会抛出 ValueError: No JSON object could be decoded
异常。
3.4 原始套接字响应
如果想获取来自服务器的原始套接字响应,可以取得 r.raw 。 不过需要在初始请求中设置 stream=True 。
r = requests.get('https://github.com/timeline.json', stream=True)
r.raw
<urllib3.response.HTTPResponse object at 0x000001E6D35CA240>
4. 响应头
我们可以查看以一个 Python 字典形式展示的服务器响应头:
import requests
r = requests.get("https://blog.domineto.top")
r.headers
{
'Server': 'nginx/1.14.2',
'Date': 'Tue, 16 Apr 2019 08:52:16 GMT',
'Content-Type': 'text/html; charset=UTF-8',
'Transfer-Encoding': 'chunked',
'Connection': 'keep-alive',
'X-Pingback': 'https://blog.domineto.top/action/xmlrpc',
'Set-Cookie': '0b1b9504a98c8280d7d85aeaed073bd6latest_time_id=83; path=/',
'Content-Encoding': 'gzip'
}
这个字典比较特殊:它是仅为 HTTP 头部而生的。根据 RFC 2616, HTTP 头部是大小写不敏感的。因此,我们可以使用任意大写形式来访问这些响应头字段。
5. Coookies
5.1 获取Cookies
如果网站的响应里面包含了Cookies,我们也可以使用Cookies
参数来获取Cookies。
比如我访问我的首页,想查看一下Cookies,可以使用以下语句:
import requests
url = 'https://blog.domineto.top'
r = requests.get(url)
print (r.cookies)
这样就可以拿到网站的Cookies信息了。
5.2 发送Cookies
Cookies变量不仅可以让我们获取Cookies信息,还可以向服务器发送 cookies 信息:
import requests
url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working')
r = requests.get(url, cookies=cookies)
print (r.text)
'{"cookies": {"cookies_are": "working"}}'
可以看到我们已经成功向服务器发送了 cookies。
6. 超时配置
可以利用 timeout 变量来配置最大请求时间:
requests.get('http://github.com', timeout=0.001)
也就是说,这个时间只限制请求的时间。即使返回的 response 包含很大内容,下载需要一定时间,也不会去限制。
7. 会话对象
在以上的请求中,每次请求其实都相当于发起了一个新的请求。也就是相当于我们每个请求都用了不同的浏览器单独打开的效果。也就是它并不是指的一个会话,即使请求的是同一个网址。比如:
import requests
requests.get('http://httpbin.org/cookies/set/sessioncookie/123456789')
r = requests.get("http://httpbin.org/cookies")
print(r.text)
{
"cookies": {}
}
通过这个结果可以看出,两次请求不在同一个会话当中。那么如何使一个会话保持长久呢?可以通过以下方案来实现:
import requests
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"
}
}
发现成功获取了Cookies。
那么既然会话是一个全局的变量,那么我们肯定可以用来全局的配置了。
import requests
s = requests.Session()
s.headers.update({'x-test': 'true'})
r = s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})
print (r.text)
通过 s.headers.update 方法设置了 headers 的变量。然后我们又在请求中设置了一个 headers,那么会出现什么结果?
很简单,两个变量都传送过去了。
{
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.9.1",
"X-Test": "true",
"X-Test2": "true"
}
}
如果get方法传的headers 同样也是 x-test 呢?
r = s.get('http://httpbin.org/headers', headers={'x-test': 'true'})
嗯,它会覆盖掉全局的配置:
{
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.9.1",
"X-Test": "true"
}
}
那如果不想要全局配置中的一个变量了呢?很简单,设置为 None 即可
r = s.get('http://httpbin.org/headers', headers={'x-test': None})
{
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.9.1",
}
}
关于Requests库还是要多用了之后才会有更深的理解,所以很多功能我用过了再总结吧。