现代爬虫技术:Session与Cookie机制详解

你有没有遇到过这种爬虫入门拦路虎: 明明用requests库发了「登录接口POST请求」,用户名密码也全对,再去爬「我的订单/个人中心」,却直接返回 401 Unauthorized 或跳回登录页?

核心原因就藏在「HTTP是无状态协议」里——服务器压根记不住刚才是谁登的。而解决这个问题的「Web标配身份通行证」,就是我们今天要聊的 Cookie + Session


1. 从无状态到状态管理的演进(极简版)

1.1 早期静态网页的“纯文本困境”

早期的网页全是写死的HTML文件,比如:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>2000年的个人主页</title>
</head>
<body>
    <h1>欢迎来到张三的静态页!</h1>
    <p>每天只能手动改代码更新内容...</p>
</body>
</html>
  • ✅ 优点:服务器压力极小、加载快到飞起、随便丢个Apache/Nginx就能跑
  • ❌ 问题:完全没法区分用户——不管是张三、李四、还是黑客,看到的都是一模一样的死内容

1.2 动态网页催生的「身份需求」

后来PHP、ASP、Java Web这些技术出现了,网页可以根据请求实时生成内容,但新问题又来了:

用户登录一次后,浏览购物车、提交订单时,怎么让服务器一直知道这是同一个登录用户

HTTP协议天生“健忘”,每次请求都是独立的陌生人对话——所以必须给每个对话加个「身份标签」,这就是Cookie和Session的雏形。


2. Cookie:浏览器本地的「小纸条」

2.1 Cookie是什么?

简单说,Cookie是服务器塞给浏览器的、存储在本地的一串小文本数据,最大限制一般在4KB左右。

当浏览器第一次发请求给服务器时:

  1. 服务器在响应头里加一行 Set-Cookie: 标签名=标签值; 属性1; 属性2...
  2. 浏览器收到后,按照属性要求保存这个小纸条
  3. 之后每次给同一域名/路径发请求,浏览器都会自动在请求头里带一行 Cookie: 所有符合条件的标签

2.2 关键Cookie属性(爬虫必知,也是安全核心)

属性对爬虫的作用安全设置建议(爬取时尽量模仿真实网站)
DomainCookie生效的域名——比如只能给example.com发,不能给test.example.com爬取时如果跨子域名,记得检查Domain是否匹配
PathCookie生效的路径——比如只在/api下生效爬接口时别只存根域名的Cookie,可能漏接口专属的
Expires/Max-Age过期时间——无则是「会话Cookie」(关浏览器就删),有则是「持久Cookie」登录后的持久Cookie可以存下来复用(比如爬电商隔日再登)
Secure只有HTTPS请求才会带这个Cookie现在绝大多数网站都是HTTPS,爬HTTP的极少了
HttpOnly只有浏览器内核/后端接口能读,JavaScript读不到(防XSS)爬虫别试图用JS去抓这种Cookie,直接用库存就行
SameSite跨站请求带不带——Chrome默认Lax(同站跳转或导航请求才带)爬跨站嵌入的内容时要注意这个属性的限制

2.3 爬虫视角:Cookie长什么样?

用浏览器开发者工具(F12→Network→选个请求→Headers)就能看到:

  • 响应头里的Set-Cookie(服务器发的)
    Set-Cookie: JSESSIONID=abc123def456; Path=/; HttpOnly; SameSite=Lax
    Set-Cookie: user_theme=dark; Max-Age=86400; Domain=example.com
  • 请求头里的Cookie(浏览器自动带的)
    Cookie: JSESSIONID=abc123def456; user_theme=dark

3. Session:服务器上的「用户档案」

3.1 Session是什么?

Cookie虽然能存标签,但不能存敏感信息(比如用户ID、密码哈希——虽然有人存,但完全不安全,容易被窃取)。

所以Session的思路是:

  1. 服务器生成一个全球唯一的Session ID(比如刚才的JSESSIONID
  2. 把Session ID当「档案编号」,把真正的敏感信息(登录状态、用户ID、购物车)存在服务器上(内存、Redis、MySQL都行)
  3. 把Session ID通过Set-Cookie塞给浏览器
  4. 之后浏览器每次发请求,服务器先拿请求头里的Session ID去查档案——查到了就知道是谁,查不到就认为未登录

3.2 常用Session存储方案

存储方式特点常见场景
服务器内存最快,但重启服务器所有档案全丢单台小网站/测试环境
MySQL/PostgreSQL持久化,不会丢,但查询慢小流量、需要长期存的场景
Redis(主流推荐)极快,支持过期时间自动删档案,适合分布式中大型电商、社交平台
JWT(无状态替代)档案直接存在客户端的加密Token里,服务器不用存——但Token不能主动删移动端APP、前后端分离API

4. 爬虫如何处理Session和Cookie?(核心代码)

新手常犯的错误:每次请求都用 requests.get/post() 单独发——这样每次都是「新的浏览器会话」,Cookie不会自动继承,自然登不上。

4.1 基础:用requests.Session()自动管理Cookie

requests库的 Session 对象是模拟浏览器会话的神器,会自动保存、更新、携带Cookie:

import requests

# 1. 创建一个「浏览器会话」
session = requests.Session()

# 2. 设置UA(伪装成Chrome,不然很多网站会拦截)
session.headers.update({
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
})

# 3. 发登录请求(Cookie会自动存在session里)
login_url = "https://example.com/api/login"
login_data = {"username": "test_user", "password": "test_password123"}
resp = session.post(login_url, data=login_data)

# 4. 检查登录是否成功(比如看状态码、响应JSON里的code)
if resp.status_code == 200 and resp.json().get("code") == 0:
    print("登录成功!")
else:
    print(f"登录失败:{resp.text}")

# 5. 后续请求直接用session发,自动带Cookie
profile_url = "https://example.com/api/profile"
profile_resp = session.get(profile_url)
print(profile_resp.text)  # 这里就能拿到个人中心的数据了

4.2 进阶:Cookie持久化(不用每次都登录)

如果要爬的网站Session过期时间很长(比如一周),可以把Cookie存到本地文件,下次直接加载:

import requests
import pickle  # Python标准库,用来序列化对象

# 登录成功后保存Cookie
with open("example_cookies.pkl", "wb") as f:
    pickle.dump(session.cookies, f)

# 下次运行时先加载Cookie
session = requests.Session()
with open("example_cookies.pkl", "rb") as f:
    session.cookies.update(pickle.load(f))

# 加载后先验证Cookie是否有效(比如访问个人中心)
profile_resp = session.get(profile_url)
if "test_user" in profile_resp.text:
    print("Cookie有效,免登录成功!")
else:
    print("Cookie过期了,需要重新登录")

5. 爬虫需要注意的安全与合规问题

5.1 反爬相关的小细节

  • 别直接用requests库默认的UA:很多网站会把默认UA加入黑名单
  • 请求频率别太高:不然会被封IP,可以加 time.sleep() 或用代理池
  • 尽量模仿真实浏览器的请求顺序:比如先访问首页,再点击登录按钮(先爬登录页拿隐藏的CSRF Token),再发登录请求

5.2 道德与法律合规

  • 遵守网站的robots.txt协议:虽然没有强制力,但这是爬虫的基本道德
  • 不要爬取敏感个人信息:比如身份证号、手机号、银行卡号
  • 不要过度消耗网站的服务器资源:比如同时开1000个线程爬小网站
  • 尽量用公开的API:如果网站有官方API,优先用API而不是爬虫

6. 总结

今天我们聊了:

  1. 为什么需要Session和Cookie:解决HTTP无状态的问题
  2. Cookie是什么:浏览器本地的小纸条,存标签
  3. Session是什么:服务器上的用户档案,存敏感信息
  4. 爬虫如何处理:用 requests.Session() 自动管理,用 pickle 持久化
  5. 安全与合规:别被封,别违法

作为爬虫开发者,深入理解Session和Cookie的工作原理是入门必备技能,同时也要注意遵守网站规则和法律法规。


参考资源

  1. MDN Web Docs - HTTP Cookies
  2. OWASP Session Management Cheat Sheet
  3. requests库官方文档 - Session Objects