Requests Cookie的发送与管理

Cookie是HTTP协议中用于在客户端存储会话信息的重要机制。Requests库提供了完整的Cookie支持,包括发送、接收、存储和管理。

Cookie概述

Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。

Cookie基本概念

Requests中的Cookie表示:
  • 字典形式 - {'name': 'value'},简单但无法设置属性
  • CookieJar对象 - requests.cookies.RequestsCookieJar,完整支持Cookie属性
  • Cookie对象 - http.cookiejar.Cookie,标准库Cookie对象

Cookie属性详解

发送Cookie

Requests提供了多种发送Cookie的方式,可以根据需求选择合适的方法。

方法1:使用cookies参数
import requests

url = "https://httpbin.org/cookies"

# 最简单的Cookie发送方式
cookies = {
    'session_id': 'abc123',
    'user_id': '456',
    'theme': 'dark'
}

response = requests.get(url, cookies=cookies)

print(f"状态码: {response.status_code}")
if response.status_code == 200:
    data = response.json()
    print(f"发送的Cookie: {data['cookies']}")
方法2:使用CookieJar
import requests
from requests.cookies import RequestsCookieJar

url = "https://httpbin.org/cookies"

# 创建CookieJar对象
jar = RequestsCookieJar()

# 添加Cookie(可以设置属性)
jar.set('session_id', 'abc123',
        domain='httpbin.org',
        path='/cookies')
jar.set('user_id', '456',
        domain='httpbin.org',
        path='/')

response = requests.get(url, cookies=jar)

print(f"状态码: {response.status_code}")
if response.status_code == 200:
    data = response.json()
    print(f"发送的Cookie: {data['cookies']}")

复杂的Cookie发送示例

Cookie发送注意事项:
  • 自动编码 - Requests会自动对Cookie值进行URL编码
  • 大小限制 - 单个Cookie通常不超过4KB
  • 数量限制 - 每个域名通常不超过50个Cookie
  • 属性限制 - 字典形式的Cookie无法设置属性(domain, path等)
  • 敏感信息 - 避免在Cookie中存储敏感信息

接收Cookie

Requests可以从服务器响应中接收Cookie,并存储在响应对象的cookies属性中。

基本Cookie接收

处理多个Cookie

Cookie属性解析

Session自动管理Cookie

使用Session对象可以自动处理Cookie的发送和接收,简化Cookie管理。

不使用Session
import requests

# 不使用Session,需要手动管理Cookie
cookies = {}

# 第一次请求:获取Cookie
response1 = requests.get(
    'https://httpbin.org/cookies/set/session/abc123'
)
# 手动保存Cookie
for cookie in response1.cookies:
    cookies[cookie.name] = cookie.value

# 第二次请求:手动携带Cookie
response2 = requests.get(
    'https://httpbin.org/cookies',
    cookies=cookies
)

print(f"第一次请求状态码: {response1.status_code}")
print(f"第二次请求状态码: {response2.status_code}")
print(f"手动管理的Cookie: {cookies}")
使用Session
import requests

# 使用Session,自动管理Cookie
session = requests.Session()

# 第一次请求:自动保存Cookie
response1 = session.get(
    'https://httpbin.org/cookies/set/session/abc123'
)

# 第二次请求:自动携带Cookie
response2 = session.get('https://httpbin.org/cookies')

print(f"第一次请求状态码: {response1.status_code}")
print(f"第二次请求状态码: {response2.status_code}")

# 查看Session中的Cookie
print(f"Session中的Cookie数量: {len(session.cookies)}")
for cookie in session.cookies:
    print(f"  {cookie.name}: {cookie.value}")
使用Session的优势:
  • 自动Cookie管理 - 无需手动保存和发送Cookie
  • 跨请求保持状态 - 模拟浏览器会话行为
  • 性能优化 - 连接池重用,减少连接建立时间
  • 简化代码 - 减少重复的Cookie处理代码
  • 属性保持 - 保持Cookie的domain、path等属性

完整Session示例

Session的Cookie策略

Cookie持久化存储

将Cookie保存到文件或数据库,以便在不同运行会话之间保持登录状态。

方法1:文件存储
import pickle
import requests
from requests.cookies import RequestsCookieJar

def save_cookies_to_file(cookie_jar, filename):
    """保存CookieJar到文件"""
    with open(filename, 'wb') as f:
        pickle.dump(cookie_jar, f)
    print(f"Cookie已保存到 {filename}")

def load_cookies_from_file(filename):
    """从文件加载CookieJar"""
    try:
        with open(filename, 'rb') as f:
            cookie_jar = pickle.load(f)
        print(f"Cookie已从 {filename} 加载")
        return cookie_jar
    except FileNotFoundError:
        print(f"文件 {filename} 不存在,返回空的CookieJar")
        return RequestsCookieJar()

# 使用示例
session = requests.Session()

# 获取一些Cookie
session.get('https://httpbin.org/cookies/set/test_cookie/persisted_value')

# 保存Cookie
save_cookies_to_file(session.cookies, 'cookies.pkl')

# 新会话中加载
new_session = requests.Session()
new_session.cookies = load_cookies_from_file('cookies.pkl')

# 验证加载的Cookie
response = new_session.get('https://httpbin.org/cookies')
if response.status_code == 200:
    data = response.json()
    print(f"加载的Cookie: {data.get('cookies', {})}")
方法2:JSON存储
import json
import requests
from requests.cookies import RequestsCookieJar
from http.cookiejar import Cookie

class JSONCookieStorage:
    """JSON格式的Cookie存储"""

    @staticmethod
    def save(cookie_jar, filename):
        """保存CookieJar为JSON"""
        cookies_data = []

        for cookie in cookie_jar:
            cookie_dict = {
                'name': cookie.name,
                'value': cookie.value,
                'domain': cookie.domain,
                'path': cookie.path,
                'expires': cookie.expires,
                'secure': cookie.secure,
                'rest': cookie.rest
            }
            cookies_data.append(cookie_dict)

        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(cookies_data, f, indent=2, ensure_ascii=False)

        print(f"Cookie已保存为JSON到 {filename}")

    @staticmethod
    def load(filename):
        """从JSON加载CookieJar"""
        jar = RequestsCookieJar()

        try:
            with open(filename, 'r', encoding='utf-8') as f:
                cookies_data = json.load(f)

            for cookie_dict in cookies_data:
                cookie = Cookie(
                    version=0,
                    name=cookie_dict['name'],
                    value=cookie_dict['value'],
                    port=None,
                    port_specified=False,
                    domain=cookie_dict['domain'],
                    domain_specified=bool(cookie_dict['domain']),
                    domain_initial_dot=cookie_dict['domain'].startswith('.') if cookie_dict['domain'] else False,
                    path=cookie_dict['path'],
                    path_specified=bool(cookie_dict['path']),
                    secure=cookie_dict['secure'],
                    expires=cookie_dict['expires'],
                    discard=False,
                    comment=None,
                    comment_url=None,
                    rest=cookie_dict.get('rest', {}),
                    rfc2109=False
                )
                jar.set_cookie(cookie)

            print(f"Cookie已从JSON文件 {filename} 加载")
        except FileNotFoundError:
            print(f"文件 {filename} 不存在")

        return jar

完整的Cookie管理器

Cookie安全

Cookie安全对于保护用户会话和敏感信息至关重要。

Cookie安全风险:
  • 会话劫持 - 攻击者窃取Cookie冒充用户
  • 跨站脚本(XSS) - 通过JavaScript窃取Cookie
  • 跨站请求伪造(CSRF) - 利用用户的Cookie发起恶意请求
  • 信息泄露 - Cookie中存储敏感信息
  • 中间人攻击 - 在传输过程中窃取Cookie

安全Cookie设置

高级Cookie操作

1. 域名和路径匹配

2. Cookie监控和审计

总结

本章详细介绍了Requests库中Cookie的发送与管理:

  1. Cookie基本概念 - Cookie的组成、属性和作用
  2. 发送Cookie - 使用cookies参数或CookieJar发送Cookie
  3. 接收Cookie - 从响应中获取Cookie并解析属性
  4. Session管理 - 使用Session对象自动管理Cookie,跨请求保持状态
  5. CookieJar对象 - Requests中的Cookie容器,支持完整Cookie属性
  6. 持久化存储 - 将Cookie保存到文件、JSON或数据库
  7. Cookie安全 - Secure、HttpOnly、SameSite等安全属性
  8. 高级操作 - 域名路径匹配、Cookie监控、审计等

最佳实践建议:

  • 对于需要保持登录状态的场景,使用Session对象
  • 生产环境中考虑Cookie的持久化存储
  • 始终设置安全的Cookie属性(Secure、HttpOnly、SameSite)
  • 避免在Cookie中存储敏感信息
  • 定期清理过期的Cookie
  • 监控Cookie的使用情况,发现异常及时处理