杰瑞科技汇

Python 如何自定义 Cookie?

下面我将从基础到高级,分步讲解如何自定义 Cookie。

核心概念

  • http.cookiejar.CookieJar: 这是 http.cookiejar 模块的核心类,它像一个容器,用来存储和管理所有的 Cookie。
  • http.cookiejar.MozillaCookieJar / http.cookiejar.LWPCookieJar: 这两个是 CookieJar 的子类,它们可以将 Cookie 持久化保存到文件中,就像浏览器一样。MozillaCookieJar 兼容 Mozilla/Netscape 格式,LWPCookieJar 兼容 libwww-perl (LWP) 格式,我们通常使用 MozillaCookieJar
  • urllib.request.build_opener: 我们需要用它来创建一个可以自动处理 Cookie 的“opener”(打开器)。
  • urllib.request.HTTPHandler / HTTPSHandler: 用于处理 HTTP 和 HTTPS 请求。
  • urllib.request.HTTPCookieProcessor: 这是关键,它将 CookieJaropener 关联起来,使得 opener 在发送请求时能自动带上 Cookie,并在收到响应时自动保存新的 Cookie。

基础用法:创建并使用 CookieJar

这个例子演示了如何创建一个 CookieJar,并用它来发送一个请求,服务器返回的 Cookie 会被自动保存到 CookieJar 中。

import urllib.request
import urllib.parse
import http.cookiejar
# 1. 创建一个 CookieJar 实例
cookie_jar = http.cookiejar.CookieJar()
# 2. 创建一个 HTTPCookieProcessor,并将 CookieJar 传给它
cookie_handler = urllib.request.HTTPCookieProcessor(cookie_jar)
# 3. 创建一个 opener,将 cookie_handler 添加进去
opener = urllib.request.build_opener(cookie_handler)
# 4. 使用 opener 发送请求
# 注意:这里用一个需要登录的网站作为示例,你需要替换成你自己的目标 URL
# 访问一个需要登录才能访问的页面
# url = "https://example.com/protected-page"
# 为了演示,我们用一个能设置 Cookie 的简单网站
url = "http://httpbin.org/cookies/set?test_cookie=12345"
try:
    response = opener.open(url)
    # 5. 读取并打印响应内容
    html = response.read().decode('utf-8')
    print("--- Response Content ---")
    print(html)
    print("------------------------\n")
    # 6. 查看保存到 CookieJar 中的 Cookie
    print("--- Cookies in CookieJar ---")
    for cookie in cookie_jar:
        print(f"Name: {cookie.name}")
        print(f"Value: {cookie.value}")
        print(f"Domain: {cookie.domain}")
        print(f"Path: {cookie.path}")
        print(f"Expires: {cookie.expires}")
        print("------------------------")
except urllib.error.URLError as e:
    print(f"Error opening URL: {e.reason}")

代码解释:

  1. http.cookiejar.CookieJar(): 创建一个空的“饼干罐”。
  2. HTTPCookieProcessor(cookie_jar): 创建一个处理器,告诉 urllib:“请使用这个 cookie_jar 来管理所有 Cookie”。
  3. build_opener(cookie_handler): 创建一个“开门器”,这个开门器包含了我们刚刚配置好的 Cookie 处理能力。
  4. opener.open(url): 当我们用这个开门器去打开 URL 时,它会自动完成以下事情:
    • 检查 cookie_jar 中是否有匹配该 URL 的 Cookie,如果有,就自动添加到请求头中。
    • 发送请求。
    • 接收服务器响应,如果响应头中有 Set-Cookie,就解析它并存入 cookie_jar
  5. 遍历 cookie_jar,我们可以看到从 httpbin.org 收到的 test_cookie

高级用法:手动创建和添加 Cookie

服务器可能不会通过 Set-Cookie 来给你 Cookie,或者你需要手动设置一个特定的 Cookie 来访问某个接口,这时,我们可以手动创建 Cookie 对象并添加到 CookieJar 中。

http.cookiejar.Cookie 对象的构造函数签名如下: Cookie(version, name, value, port, port_specified, domain, domain_specified, domain_initial_dot, path, path_specified, secure, expires, discard, comment, comment_url, rest, rfc2109=False)

这看起来很复杂,但我们可以使用 http.cookiejar.CookieJarset_cookie 方法,它会更方便地处理这些细节。

import http.cookiejar
from urllib.parse import urlparse
# 1. 创建一个 CookieJar
cookie_jar = http.cookiejar.CookieJar()
# 2. 手动创建一个 Cookie 对象
# 假设我们要为 'example.com' 设置一个名为 'user_id' 的 Cookie,值为 'abc123'
# 注意:domain 必须包含点,'example.com' 而不是 'example'
new_cookie = http.cookiejar.Cookie(
    version=0,
    name='user_id',
    value='abc123',
    port=None,
    port_specified=False,
    domain='httpbin.org',  # 目标域名
    domain_specified=True,
    domain_initial_dot=False,
    path='/cookies',       # Cookie 有效的路径
    path_specified=True,
    secure=False,          # 是否仅 HTTPS 传输
    expires=None,          # 会话 Cookie,浏览器关闭后失效
    discard=True,          # 是否在会话结束后丢弃
    comment=None,
    comment_url=None,
    rest={'HttpOnly': None} # 可以添加额外的属性,如 HttpOnly, SameSite
)
# 3. 将手动创建的 Cookie 添加到 CookieJar
cookie_jar.set_cookie(new_cookie)
# 4. 创建 opener (和之前一样)
cookie_handler = urllib.request.HTTPCookieProcessor(cookie_jar)
opener = urllib.request.build_opener(cookie_handler)
# 5. 发送请求,验证 Cookie 是否被带上
# httpbin.org/cookies 会返回请求中携带的所有 Cookie
url = "http://httpbin.org/cookies"
try:
    response = opener.open(url)
    html = response.read().decode('utf-8')
    print("--- Response Content (should show our manual cookie) ---")
    print(html)
    print("--------------------------------------------------------\n")
    # 6. 再次查看 CookieJar
    print("--- Cookies in CookieJar (after manual addition) ---")
    for cookie in cookie_jar:
        print(cookie)
    print("----------------------------------------------------")
except urllib.error.URLError as e:
    print(f"Error opening URL: {e.reason}")

代码解释:

  1. 我们创建了一个 Cookie 对象,并详细指定了它的 name, value, domain, path 等属性。
  2. cookie_jar.set_cookie(new_cookie): 将我们“捏”出来的这个 Cookie 放进了饼干罐。
  3. 后续步骤和基础用法一样,当我们用这个 opener 访问 httpbin.org/cookies 时,请求中就会包含我们手动设置的 user_id=abc123

持久化存储:将 Cookie 保存到文件并读取

模拟真实浏览器,我们需要把 Cookie 保存下来,下次程序运行时直接加载,而不需要重新登录。

import http.cookiejar
import urllib.request
# --- 1. 第一次运行:保存 Cookie 到文件 ---
# 创建一个 MozillaCookieJar 实例,并指定文件名
cookie_file = 'my_cookies.txt'
cookie_jar = http.cookiejar.MozillaCookieJar(cookie_file)
# 创建 opener
cookie_handler = urllib.request.HTTPCookieProcessor(cookie_jar)
opener = urllib.request.build_opener(cookie_handler)
# 模拟登录或获取 Cookie 的请求
# httpbin.org/cookies/set 会设置一个 Cookie
print("--- First Run: Fetching and saving cookies... ---")
opener.open("http://httpbin.org/cookies/set/session_id=98765")
# 保存 Cookie 到文件
# ignore_discard=True: 保存那些被标记为会话结束就丢弃的 Cookie
# ignore_expires=True: 保存那些已经过期的 Cookie (通常为了调试)
cookie_jar.save(ignore_discard=True, ignore_expires=True)
print(f"Cookies saved to {cookie_file}\n")
# --- 2. 第二次运行:从文件加载 Cookie ---
# 创建一个新的 MozillaCookieJar 实例
cookie_jar_loaded = http.cookiejar.MozillaCookieJar(cookie_file)
try:
    # 尝试从文件加载 Cookie
    cookie_jar_loaded.load(ignore_discard=True, ignore_expires=True)
    print(f"--- Second Run: Cookies loaded from {cookie_file} ---")
    # 创建新的 opener
    cookie_handler_loaded = urllib.request.HTTPCookieProcessor(cookie_jar_loaded)
    opener_loaded = urllib.request.build_opener(cookie_handler_loaded)
    # 发送请求,验证加载的 Cookie 是否生效
    response = opener_loaded.open("http://httpbin.org/cookies")
    html = response.read().decode('utf-8')
    print("--- Response Content (should show loaded cookie) ---")
    print(html)
    print("-----------------------------------------------------")
except FileNotFoundError:
    print(f"Cookie file {cookie_file} not found. This is expected on the first run.")
except http.cookiejar.LoadError as e:
    print(f"Error loading cookies: {e}. The file might be corrupted.")

代码解释:

  1. http.cookiejar.MozillaCookieJar(cookie_file): 创建一个支持文件存储的 CookieJar
  2. cookie_jar.save(...): 将当前 CookieJar 中的所有 Cookie 保存到指定文件。
  3. cookie_jar.load(...): 从文件中读取 Cookie 并加载到 CookieJar 实例中。
  4. 通过 ignore_discard=Trueignore_expires=True,我们可以确保即使是一些临时或过期的 Cookie 也能被保存和加载,这对于某些场景很有用。
场景 核心步骤 关键代码/类
基础使用 创建 CookieJar -> 创建 HTTPCookieProcessor -> 创建 opener -> 发送请求 CookieJar, HTTPCookieProcessor, build_opener
手动创建 Cookie 创建 Cookie 对象 -> 用 set_cookie 添加到 CookieJar -> 后续步骤同上 Cookie, CookieJar.set_cookie()
持久化存储 使用 MozillaCookieJar -> save() 保存到文件 -> load() 从文件加载 MozillaCookieJar, .save(), .load()

掌握了这些方法,你就可以在 Python 中灵活地处理各种与 Cookie 相关的任务了。

分享:
扫描分享到社交APP
上一篇
下一篇