Requests库爬虫进阶:手把手教你处理登录态与会话保持(Session & Cookies实战)
·
Requests库爬虫进阶:手把手教你处理登录态与会话保持(Session & Cookies实战)
当你需要爬取用户中心、订单列表等需要登录才能访问的页面时,简单的请求已经无法满足需求。这时,会话保持和登录态管理就成了爬虫开发中的关键技能。本文将深入探讨如何使用Requests库的Session对象来自动管理Cookies,实现跨请求的会话保持。
1. 为什么需要会话保持
想象一下这样的场景:你手动登录一个网站后,可以自由浏览个人主页、查看订单、修改资料。但当你用爬虫模拟登录后,却发现后续请求总是返回未登录状态。这就是典型的会话保持问题。
传统做法是手动管理Cookies:
import requests
# 第一次请求获取Cookies
login_response = requests.post(login_url, data=credentials)
cookies = login_response.cookies
# 后续请求手动传递Cookies
profile_response = requests.get(profile_url, cookies=cookies)
这种方法虽然可行,但存在几个明显问题:
- 需要手动提取和传递Cookies
- 无法自动处理Cookies更新
- 代码冗余且容易出错
Session对象正是为解决这些问题而设计的。它会在同一个会话中自动处理Cookies的存储和传递,就像浏览器一样工作。
2. Session对象的核心优势
使用Session对象与直接传递Cookies字典的主要区别:
| 特性 | Session对象 | 手动传递Cookies |
|---|---|---|
| Cookies自动管理 | ✅ 自动存储和发送 | ❌ 需要手动处理 |
| 连接池复用 | ✅ 提升性能 | ❌ 每次新建连接 |
| 持久性参数 | ✅ 可设置默认headers | ❌ 每次需单独设置 |
| Cookies更新 | ✅ 自动处理 | ❌ 需手动更新 |
一个基础Session使用示例:
with requests.Session() as session:
# 设置公共headers
session.headers.update({
'User-Agent': 'Mozilla/5.0',
'Referer': 'https://example.com'
})
# 登录请求(自动保存Cookies)
session.post(login_url, data=credentials)
# 后续请求自动携带Cookies
profile = session.get(profile_url).json()
3. 实战:从浏览器提取Cookies
有时我们需要从已登录的浏览器会话中提取Cookies,用于爬虫初始化。以下是具体步骤:
- 在Chrome中打开开发者工具(F12)
- 访问目标网站并登录
- 切换到"Application"标签
- 在左侧选择"Cookies"下的网站域名
- 右键点击Cookies选择"Copy as Node.js fetch"
获取到的Cookies可以这样转换为Python字典:
def parse_browser_cookies(cookie_str):
cookies = {}
for item in cookie_str.split(';'):
key, value = item.strip().split('=', 1)
cookies[key] = value
return cookies
# 示例使用
browser_cookies = "name=value; path=/; domain=.example.com"
session.cookies.update(parse_browser_cookies(browser_cookies))
注意:浏览器Cookies通常有过期时间,直接使用可能面临会话过期问题。建议结合登录流程使用。
4. 高级会话管理技巧
4.1 Cookies持久化存储
为了避免每次重启爬虫都需要重新登录,我们可以将Cookies持久化到文件:
import pickle
import os
def save_cookies(session, filename):
with open(filename, 'wb') as f:
pickle.dump(session.cookies, f)
def load_cookies(session, filename):
if os.path.exists(filename):
with open(filename, 'rb') as f:
session.cookies.update(pickle.load(f))
# 使用示例
session = requests.Session()
load_cookies(session, 'cookies.pkl')
try:
session.post(login_url, data=credentials)
save_cookies(session, 'cookies.pkl')
except Exception as e:
print(f"登录失败: {e}")
4.2 处理动态Cookies
某些网站会在每次请求时更新Cookies,这时需要实时获取最新Cookies:
response = session.get(api_url)
updated_cookies = response.cookies
# 获取特定Cookie值
session_id = session.cookies.get('sessionid')
# 检查登录状态
if 'auth_token' not in session.cookies:
print("会话已过期,需要重新登录")
4.3 多账号会话隔离
当需要管理多个账号时,可以为每个账号创建独立的Session:
class AccountSession:
def __init__(self, username, password):
self.session = requests.Session()
self.credentials = {'username': username, 'password': password}
def login(self):
self.session.post(login_url, data=self.credentials)
def get_profile(self):
return self.session.get(profile_url).json()
# 使用示例
account1 = AccountSession('user1', 'pass1')
account2 = AccountSession('user2', 'pass2')
5. 常见问题与解决方案
5.1 会话过期处理
实现自动检测会话状态并在过期时重新登录:
def safe_request(session, url, max_retry=3):
for _ in range(max_retry):
try:
response = session.get(url)
if 'login' in response.url: # 被重定向到登录页
session.post(login_url, data=credentials)
continue
return response
except requests.RequestException as e:
print(f"请求失败: {e}")
return None
5.2 验证码处理
当登录需要验证码时,可以这样处理:
- 首次请求获取验证码图片
- 人工识别或使用OCR识别
- 提交验证码
# 获取验证码
captcha_response = session.get(captcha_url)
with open('captcha.jpg', 'wb') as f:
f.write(captcha_response.content)
# 人工输入验证码(或调用OCR服务)
captcha_code = input("请输入验证码: ")
# 提交登录请求
login_data = {
**credentials,
'captcha': captcha_code
}
session.post(login_url, data=login_data)
5.3 请求频率控制
避免因请求过快被封禁:
import time
from random import uniform
def throttled_request(session, url, delay=(1, 3)):
time.sleep(uniform(*delay)) # 随机延迟
return session.get(url)
在实际项目中,我发现最稳定的做法是模拟真实用户行为:在关键操作间加入随机延迟,避免规律性请求。同时,合理设置User-Agent和Referer等头部信息,能让爬虫行为更接近正常浏览器访问。
更多推荐


所有评论(0)