4. Python Requests库实战:从安装到Cookie管理

说实话,Python做网络请求,Requests库几乎是绕不开的选择。我最早用urllib的时候,那叫一个痛苦——手动拼接参数、处理编码、管理Cookie,写出来的代码又臭又长。后来换了Requests,感觉整个世界都清爽了。

这一章,咱们就把Requests库的核心用法过一遍。从安装开始,到GET/POST请求、参数处理、响应解析,最后聊到会话和Cookie管理。嗯,都是实战里天天用的东西。

4.1 安装与导入

安装很简单,一行命令搞定:

pip install requests

我个人习惯在虚拟环境里装,避免污染全局Python。如果你用的是Anaconda,也可以:

conda install requests

装完之后,导入就一句话:

import requests

这就够了。我见过有人写 from requests import *,其实没必要,保持命名空间干净比较好。

小提示: 如果你在公司内网,可能需要配置代理。Requests会自动读取环境变量 HTTP_PROXY 和 HTTPS_PROXY,不用额外设置。

4.2 发送GET请求

GET请求是最常见的。说白了,就是从服务器拿数据。比如我们抓取一个网页:

import requests

url = "https://api.github.com/users/octocat"
response = requests.get(url)

print(response.status_code)  # 200
print(response.text)         # 响应内容(字符串形式)

你看,就这么几行。我曾经在项目里用这个接口抓GitHub用户信息,结果忘了处理超时,程序卡了半小时。所以,我建议你加上超时参数:

response = requests.get(url, timeout=5)  # 5秒超时
注意: 不设置timeout的话,请求可能会一直挂起。特别是批量采集的时候,一个卡住,后面全完蛋。

4.3 发送POST请求

POST请求通常用来提交数据。比如登录、提交表单。用法和GET差不多,只是多了一个 data 参数:

url = "https://httpbin.org/post"
payload = {"username": "admin", "password": "123456"}
response = requests.post(url, data=payload)

print(response.json())  # 解析JSON响应

为什么会用 data 而不是 params?因为POST的数据是放在请求体里的,不是URL上。你想想看,如果密码明文出现在URL里,那多危险。

如果服务器要求JSON格式,那就用 json 参数:

response = requests.post(url, json=payload)

Requests会自动帮你设置 Content-Type: application/json。这个细节,我当年踩过坑——手动设header,结果格式不对,服务器一直返回400。

4.4 处理请求参数

参数处理分两种:URL查询参数和请求体参数。

4.4.1 URL查询参数(GET)

用 params 参数,Requests会自动拼接到URL后面:

url = "https://api.github.com/search/repositories"
params = {"q": "requests", "sort": "stars"}
response = requests.get(url, params=params)

print(response.url)  # 实际请求的URL

输出结果:

https://api.github.com/search/repositories?q=requests&sort=stars

你看,省去了手动拼接的麻烦。而且Requests会自动处理特殊字符的编码,比如中文、空格什么的。

4.4.2 请求体参数(POST)

前面已经演示过了,用 data 或 json。这里补充一个场景:文件上传。

files = {"file": open("data.csv", "rb")}
response = requests.post(url, files=files)

我在做数据采集时,经常需要上传文件到服务器做批处理。用 files 参数,Requests会自动设置 multipart/form-data 编码。

4.5 处理响应内容

拿到响应之后,怎么提取数据?这是关键。

属性/方法 说明 示例
response.text 字符串形式响应(自动解码) print(r.text)
response.content 字节形式响应(二进制数据) r.content.decode('utf-8')
response.json() 解析为Python字典/列表 data = r.json()
response.status_code HTTP状态码 if r.status_code == 200
response.headers 响应头(字典形式) r.headers['Content-Type']
response.encoding 编码方式 r.encoding = 'utf-8'

我常用的套路是:先检查状态码,再解析JSON。如果状态码不是200,说明请求有问题,直接抛异常:

response.raise_for_status()  # 状态码不是200时抛出HTTPError

嗯,这个 raise_for_status() 是我最喜欢的函数之一。省去了手动判断的麻烦。

核心原则: 永远不要假设请求成功。先检查状态码,再处理数据。这是数据采集的底线。

4.6 会话与Cookie管理

很多网站需要登录才能访问数据。这时候就需要管理Cookie了。Requests提供了 Session 对象,可以自动保持Cookie。

4.6.1 使用Session

session = requests.Session()

# 第一次请求:登录
login_url = "https://example.com/login"
login_data = {"username": "user", "password": "pass"}
session.post(login_url, data=login_data)

# 第二次请求:访问需要登录的页面
profile_url = "https://example.com/profile"
response = session.get(profile_url)

print(response.text)  # 已经携带了Cookie

你看,用Session之后,Cookie自动带上去了。不用手动去取Cookie再塞到Header里。我曾经在项目里手动管理Cookie,结果因为过期时间没处理好,数据采集到一半全失败了。后来改用Session,再没出过问题。

4.6.2 手动设置Cookie

有时候你需要从别的地方拿到Cookie,手动设置进去:

cookies = {"session_id": "abc123", "token": "xyz789"}
response = requests.get(url, cookies=cookies)

或者用 requests.utils.cookiejar_from_dict 转换:

from requests.utils import cookiejar_from_dict

jar = cookiejar_from_dict({"key": "value"})
response = requests.get(url, cookies=jar)

4.6.3 查看响应中的Cookie

response = requests.get(url)
print(response.cookies)  # RequestsCookieJar对象
print(dict(response.cookies))  # 转为字典

这个在调试时很有用。你可以看看服务器返回了什么Cookie,是不是你想要的。

避坑指南: 我曾经遇到过一个网站,它的Cookie是HttpOnly的,JavaScript拿不到,但Requests可以正常处理。所以,别用浏览器调试工具里的Cookie直接复制,最好用Session自动管理。

4.7 本章知识体系

下面这张图,帮你梳理Requests库的核心脉络:

Requests库核心知识体系 Requests库 安装与导入 发送GET请求 发送POST请求 处理请求参数 pip install requests params参数 data / json参数 URL查询 / 请求体 处理响应内容 text / content / json() 会话与Cookie管理 Session对象 手动设置Cookie 核心要点 Session自动管理Cookie 超时设置避免卡死 raise_for_status()检查状态

这张图把Requests库的核心功能串起来了。你从安装开始,到发送请求、处理参数、解析响应,最后管理会话和Cookie。每一步都是数据采集的必备技能。