Python requests保持会话Session:跨请求保留Cookie
讲解用requests.Session()复用TCP连接和Cookie,模拟登录后连续访问多个页面,避免每次请求都重新握手,适合需要登录态的抓取场景。
场景痛点
用requests第一次请求登录接口拿到Cookie,第二次访问需要登录的页面却又跳回登录页了。原因是裸 requests.get 每次都是全新连接,Cookie不自动带。用 Session 对象,它会自动保管Cookie、复用TCP连接,登录一次后面随便逛,和浏览器行为一致。
用到的库
pip install requests beautifulsoup4 lxml
完整代码
# 导入requests
import requests
def demo_session():
# 创建一个Session对象,后续所有请求都用它发
session = requests.Session()
# 统一设置请求头,所有请求自动带上
session.headers.update({
"User-Agent": ("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36"),
})
# 第一步:模拟登录(这里用httpbin演示,真实场景换成你的登录接口)
login_url = "https://httpbin.org/post"
login_data = {"username": "demo", "password": "123456"}
resp1 = session.post(login_url, data=login_data, timeout=10)
print("登录请求状态:", resp1.status_code)
# Session会自动保存服务器下发的Cookie
print("当前Cookie:", dict(session.cookies))
# 第二步:用同一个Session访问需要登录的页面,Cookie自动带上
# httpbin/headers会回显我们这次请求带了什么头和Cookie
resp2 = session.get("https://httpbin.org/headers", timeout=10)
print("第二次请求状态:", resp2.status_code)
print("第二次请求带的头:")
print(resp2.text)
# 第三步:也可以手动设置Cookie
session.cookies.set("token", "abc123xyz", domain="httpbin.org")
resp3 = session.get("https://httpbin.org/cookies", timeout=10)
print("手动加Cookie后:")
print(resp3.text)
if __name__ == "__main__":
demo_session()
代码讲解
requests.Session()创建一个会话对象,它内部维护着Cookie jar和连接池。session.headers.update(...)设置的请求头对所有后续请求生效,不用每次都传一遍headers参数。- 用
session.post(...)登录后,服务器返回的Set-Cookie会被自动存到session.cookies里;下次session.get(...)时自动带上。 dict(session.cookies)可以查看当前存了哪些Cookie,调试时很有用。- 也可以用
session.cookies.set()手动塞入token等自定义Cookie。 - 除了Cookie,Session还会复用TCP连接(keep-alive),连续访问同一站点时速度明显更快。
运行结果
运行后依次打印登录状态、当前Cookie、第二次请求带的请求头(能看到UA是我们设置的),最后打印手动加token后的Cookie信息。全程用的都是同一个会话,没有重新握手。
注意事项
- Session不是线程安全的,多线程场景下每个线程用自己的Session。
- 用完最好
session.close(),或者用with requests.Session() as s:自动关闭。 - 登录态有过期时间,长时间任务中途要检查是否被踢回登录页。
- Session和直接requests.get相比唯一区别就是状态保持,其他用法完全一样。

更新时间:2026-09-14 20:47:50
上一篇:Python requests设置超时与重试:网络抖动自动恢复