4、Requests库实战:发送GET请求、发送POST请求、处理请求参数、设置请求头、处理响应内容、超时与重试机制
好,咱们直接进入正题。Requests 这个库,说白了就是 Python 世界里最顺手的 HTTP 工具。我做了这么多年爬虫,90% 的请求都是用 Requests 搞定的。你想想看,如果连 Requests 都玩不转,那后面的 RPA 自动化、数据抓取基本就是空中楼阁。
这一节,我会把 Requests 最核心的六个操作掰开揉碎讲清楚。每个点我都会结合自己踩过的坑来聊,保证你听完就能上手。
4.1 发送GET请求:最基础的操作
GET 请求,就是向服务器要数据。比如你打开一个网页,浏览器就在发 GET 请求。
import requests
# 最简单的GET请求
response = requests.get('https://api.github.com')
print(response.status_code) # 200 表示成功
print(response.text) # 返回的文本内容
嗯,这里要注意。很多新手以为 GET 请求就是直接访问 URL 就完事了。其实不然。我在项目中遇到过,有些网站对 GET 请求的 User-Agent 有严格校验,你不设置请求头,直接返回 403。
4.2 发送POST请求:带数据的请求
POST 请求,说白了就是给服务器提交数据。比如登录、提交表单、上传文件,都是 POST。
# 发送POST请求,带表单数据
data = {'username': 'admin', 'password': '123456'}
response = requests.post('https://httpbin.org/post', data=data)
print(response.json())
为什么会这样?因为 POST 请求的数据是放在请求体里的,不像 GET 那样直接拼在 URL 上。我刚开始做爬虫时,就犯过这个错——把 POST 参数当 GET 参数拼在 URL 里,结果服务器死活不认。
data 参数默认是表单格式,json 参数才是 JSON 格式。
4.3 处理请求参数:灵活应对各种场景
请求参数,就是 URL 问号后面的那串东西。比如 ?page=1&size=20。手动拼接太容易出错了,我建议用 params 参数。
# 使用params参数
params = {'page': 1, 'size': 20, 'keyword': 'python'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url) # 自动拼接成完整URL
你想想看,如果参数里有中文、特殊字符,手动拼接很容易出编码问题。Requests 的 params 会自动帮你做 URL 编码,省心多了。
| 参数类型 | 适用场景 | 示例 |
|---|---|---|
| params | GET请求的查询参数 | params={'key': 'value'} |
| data | POST请求的表单数据 | data={'key': 'value'} |
| json | POST请求的JSON数据 | json={'key': 'value'} |
4.4 设置请求头:伪装成正常浏览器
请求头,就是你和服务器打招呼时递上的名片。服务器一看你的名片,就知道你是浏览器还是爬虫。我见过太多新手,连 User-Agent 都不设置,直接裸奔去抓数据,结果被反爬虫系统秒封。
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'text/html,application/xhtml+xml',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Referer': 'https://www.google.com/'
}
response = requests.get('https://httpbin.org/headers', headers=headers)
我个人习惯,会把常用的请求头封装成一个字典,每次请求时直接传入。这样既统一又方便维护。我在项目中遇到过,有些网站会校验 Accept-Encoding,如果你不设置,它可能返回压缩后的数据,导致乱码。
4.5 处理响应内容:拿到数据只是第一步
响应内容,就是服务器给你的回复。可能是 HTML、JSON、图片、文件等等。怎么处理,取决于你的需求。
response = requests.get('https://api.github.com')
# 文本内容
print(response.text) # 返回字符串
# JSON内容
print(response.json()) # 自动解析为字典
# 二进制内容
print(response.content) # 返回字节流,适合下载图片
# 响应头
print(response.headers) # 返回字典
# 状态码
print(response.status_code) # 200, 404, 500等
嗯,这里有个坑。很多新手拿到 response.text 就直接用,但有时候编码不对,会出现乱码。我建议先检查 response.encoding,如果不对就手动设置。
# 手动设置编码
response.encoding = 'utf-8'
print(response.text)
4.6 超时与重试机制:让爬虫更健壮
网络请求,说白了就是不可靠的。服务器可能挂了,网络可能断了,请求可能超时。如果不设置超时,你的爬虫可能会卡死在那里,一直等下去。
# 设置超时时间(秒)
try:
response = requests.get('https://httpbin.org/delay/5', timeout=3)
except requests.exceptions.Timeout:
print('请求超时了,重试一下吧')
为什么会这样?因为有些接口响应很慢,或者网络不稳定。我建议把超时时间设置在 5-10 秒之间,太短容易误判,太长又浪费等待时间。
至于重试机制,我一般用两种方式:
- 手动重试:用循环加 try-except,失败后等几秒再试。
- 自动重试:用
requests.adapters.HTTPAdapter配合urllib3的重试策略。
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# 配置重试策略
retry_strategy = Retry(
total=3, # 总重试次数
backoff_factor=1, # 重试间隔:1, 2, 4, 8...秒
status_forcelist=[500, 502, 503, 504] # 哪些状态码需要重试
)
# 创建适配器
adapter = HTTPAdapter(max_retries=retry_strategy)
# 挂载到session
session = requests.Session()
session.mount('http://', adapter)
session.mount('https://', adapter)
# 使用session发送请求
response = session.get('https://httpbin.org/status/500')
你想想看,一个爬虫跑了一晚上,结果因为一个请求卡死了,后面的数据全没抓到,多亏啊。所以超时和重试,是每个爬虫工程师必须掌握的保命技能。
好了,Requests 库的六个核心操作就讲完了。从 GET 到 POST,从参数到请求头,从响应处理到超时重试,每一步都有讲究。我建议你把这些代码都敲一遍,遇到问题再回来翻翻。下一节,咱们聊聊 Session 和 Cookie 的管理,那才是真正进阶的开始。