Requests
1、简介
Requests 是 Python 最久负盛名的 HTTP 库,没有之一;K 神(Kenneth Reitz)的 for humans 系列中最有名的一个;
做爬虫、数据分析、接口自动化会经常用到它,非常多有名的 Python 库依赖于 Requests 提供基础能力,比如:httpx(支持异步的 HTTP 库)、locust(性能[负载]测试框架)、HttpRunner(接口自动化框架)等等,都是基于 Requests 构建起来的。
有人甚至建议将 Requests 库合入 Python 标准库发布。只要你想做 HTTP 请求,你肯定会想到 Requests。
Requests 特点:简单、简洁、优雅。
2、安装
系统环境:deepin
pip3 install requests
3、请求
3.1、导入
import requests
所有的功能都在 requests 这个名称空间下。
3.2、GET 请求
r = requests.get("https://www.baidu.com")
print(r.status_code)
print(r.text)
终端打印:
200
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equ ...... # 省略
3.3、POST 请求
https://httpbin.org
是 K 神的一个简单的 HTTP 服务,主要用于试用 requests 里面的一些功能,方便理解;
r = requests.post('https://httpbin.org/post', data={'key': 'value'})
print(r.status_code)
print(r.text)
终端打印:
200
{
"args": {},
"data": "",
"files": {},
"form": {
"key": "value"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "9",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.28.1",
"X-Amzn-Trace-Id": "Root=1-642aa9b9-259b189c1acb1e114a5d6bc7"
},
"json": null,
"origin": "110.191.179.216",
"url": "https://httpbin.org/post"
}
3.4、其他请求
其他请求方式不常用,如下:
r = requests.put('https://httpbin.org/put', data={'key': 'value'})
r = requests.delete('https://httpbin.org/delete')
r = requests.head('https://httpbin.org/get')
r = requests.options('https://httpbin.org/get')
3.5、请求头(headers)
请求头通常会加 UA(user agent),这个主要是模仿浏览器的行为,比如模仿使用 Firefox 浏览器:
headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/109.0"
}
requests.get(url, headers=headers)
requests.post(url, headers=headers)
3.6、参数
(1) get 请求参数
get 请求的参数可以直接在url后面加参数,url?key1=value1&key2=value2
,即 url 后面加问号,然后紧接着多个参数的键和值,多个键值之间用 & 符号链接;
这种方式简单是简单,但是参数多了之后,url 会变得很长,看起来胀眼睛,为了更好的可读性,requests 支持这样传递 get 请求的参数:
params = {'key1': 'value1', 'key2': 'value2'}
r = requests.get('https://httpbin.org/get', params=params)
通过打印 r.url 你会发现,实际上也是给你转换成了前面那种 & 连接的方式;
(2)post 请求参数
post 请求参数一般是通过data参数传递,通常 data 是一个字典形式:
data = {'key1': 'value1', 'key2': 'value2'}
r = requests.post('https://httpbin.org/post', data=data)
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.28.1",
"X-Amzn-Trace-Id": "Root=1-642e7884-7f20428d523e7fda1da61f1a"
},
"json": null,
"origin": "110.191.179.216",
"url": "https://httpbin.org/post"
}
如果你拿到的参数,是一个 json 格式,可以直接传递给 json 参数:
jsons = '{"key1": "value1", "key2": "value2"}'
r = requests.post('https://httpbin.org/post', json=jsons)
print(r.text)
执行后终端输出:
{
"args": {},
"data": "\"{\\\"key1\\\": \\\"value1\\\", \\\"key2\\\": \\\"value2\\\"}\"",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Content-Length": "46",
"Content-Type": "application/json",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.28.1",
"X-Amzn-Trace-Id": "Root=1-642e79d4-1f0aeb1370ea94cf2c858f9d"
},
"json": "{\"key1\": \"value1\", \"key2\": \"value2\"}",
"origin": "110.191.179.216",
"url": "https://httpbin.org/post"
}
4、响应
其实前面的例子已经有体现一点响应了;
r = requests.post('https://httpbin.org/post', data={'key': 'value'})
r 为返回值的对象(Response),通常在项目中我一般用 rsp
来表示(后面的 rsp
和 r 是一个意思,都是表示返回值的对象);
rsp 既然是对象,那来看下对象的方法和属性,咱们 Debug 跑一下就很清楚:
接下来讲几个比较常用的属性和方法;
4.1、响应内容
r.text
前面例子已经打印过,这里就不打印了;
text
的解码是自动的,大多数情况下都能正常解码;
可以通过 encoding
来查看或修改编码方式:
print(r.encoding)
r.encoding = 'ISO-8859-1'
修改编码方式之后,再使用 r.text
就会以新的编码方式解码。
如果你发现返回的内容编码不对,你可以尝试修改不同的编码,这是个经验积累的过程。
4.2、二进制响应内容
非文本类请求,一般返回的是二进制内容,此时我们应该使用 content
方法:
r.content
将二进制文件保存下来,比如请求返回一个 mp3 文件:
with open("my.mp3", "wb") as f:
f.write(r.content)
4.3、JSON响应内容
一些 RESTful API 返回通常是 json 内容,我们可以直接使用:
r.json()
获取的类型为 Python 的字典类型;
如果响应包含无效JSON,会抛 requests.exceptions.JSONDecodeError
异常。
5、高阶用法
5.1、Session
Session 对象可以在一次会话中可以有效的处理 cookie 持久化的问题;
s = requests.Session()
# 设置一个cookie为123456789
s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
# 请求一下
r = s.get('https://httpbin.org/cookies')
print(r.text)
执行后终端输出:
{
"cookies": {
"sessioncookie": "123456789"
}
}
5.2、Request
无论是前面讲到的 GET 、 POST 等请求方法:
requests.get()
requests.post()
其底层都是通过调用 Request 这个类来实现的:
class Request():
def __init__(
self,
method=None,
url=None,
headers=None,
files=None,
data=None,
params=None,
auth=None,
cookies=None,
hooks=None,
json=None,
):
pass
因此我们当然可以直接跨过这一步,不让中间商赚差价,直接用 Request:
frome requests import Request
r = Request("GET", url, headers=headers)
r = Request("POST", url, headers=headers)
还没完,记得调用一下 prepare()
方法,然后使用 Session 里面的 send 方法:
举例:
from requests import Session, Request
s = Session()
r = Request("GET", 'https://httpbin.org/get')
prepped = r.prepare()
resp = s.send(prepped)
print(resp.text)
执行终端输出:
{
"args": {},
"headers": {
"Accept-Encoding": "identity",
"Host": "httpbin.org",
"User-Agent": "python-urllib3/1.26.13",
"X-Amzn-Trace-Id": "Root=1-642e84e2-1328a0210e2252741f20c648"
},
"origin": "110.191.179.216",
"url": "https://httpbin.org/get"
}