如何在Python3+Selenium Firefox驱动首次请求前添加Cookie
问题背景
- 目标网站采用PKI认证,打开页面时会直接要求输入PIN码,导致无法在页面加载前配置已保存的Cookie
- Chrome驱动可通过
execute_cdp_cmd方法预加载Cookie,但Firefox驱动无此方法;直接未加载页面时添加Cookie会抛出错误:
selenium.common.exceptions.InvalidCookieDomainException: Message: Document is cookie-averse
Stacktrace:
WebDriverError@chrome://remote/content/shared/webdriver/Errors.jsm:186:5
InvalidCookieDomainError@chrome://remote/content/shared/webdriver/Errors.jsm:326:5
GeckoDriver.prototype.addCookie@chrome://remote/content/marionette/driver.js:1931:11
解决方案
核心思路
Firefox要求必须先建立目标域名的浏览器上下文,才能为该域名添加Cookie。因此需要先访问目标域名下的任意资源(哪怕是404资源),再加载Cookie;同时通过配置Firefox Profile优化PKI认证流程。
修正后的代码示例
import time import os import pickle from selenium import webdriver from selenium.webdriver.firefox.service import Service # 初始化Firefox Profile,配置PKI证书自动加载 firefox_profile = webdriver.FirefoxProfile() firefox_profile.set_preference("security.osclientcerts.autoload", True) # 可选:开启证书缓存,减少重复PIN输入提示 firefox_profile.set_preference("security.pki.crlite_mode", 0) # 初始化驱动(注意替换为你的geckodriver路径) driver_path = "C:\\Users\\myuser\\PycharmProjects\\myproject\\geckodriver.exe" driver = webdriver.Firefox(service=Service(driver_path), firefox_profile=firefox_profile) cookie_path = "cookies.pkl" target_url = "https://mypkiaythenticationpage.com" def get_page(): # 先访问目标域名下的资源,建立域名上下文(用favicon.ico确保几乎所有网站都能触发上下文初始化) driver.get(f"{target_url}/favicon.ico") if not os.path.isfile(cookie_path): print("未找到Cookie文件,首次加载页面生成Cookie") # 访问目标页面,首次需手动完成PIN码输入 driver.get(target_url) time.sleep(3) # 等待页面加载及Cookie生成 pickle.dump(driver.get_cookies(), open(cookie_path, "wb")) else: print("加载已保存的Cookie...") driver.delete_all_cookies() cookies = pickle.load(open(cookie_path, "rb")) for cookie in cookies: # 修正Cookie的domain格式,适配Firefox要求 if 'domain' in cookie and cookie['domain'].startswith('.'): cookie['domain'] = cookie['domain'][1:] driver.add_cookie(cookie) # 加载目标页面 driver.get(target_url) def save_last_cookie_state(): print("保存最新Cookie状态...") pickle.dump(driver.get_cookies(), open(cookie_path, "wb")) if __name__ == '__main__': try: get_page() time.sleep(5) # 可根据实际页面加载情况调整等待时间 save_last_cookie_state() finally: driver.quit()
关键说明
- 域名上下文初始化:先访问
target_url/favicon.ico是解决Document is cookie-averse错误的核心,这一步会让Firefox为目标域名创建上下文,之后即可正常添加Cookie - PKI认证优化:
security.osclientcerts.autoload配置会让Firefox自动加载系统中的PKI证书,部分场景下可自动完成认证,无需手动输入PIN(取决于证书本身的访问权限设置) - Cookie格式修正:部分保存的Cookie会带
.前缀的domain,去掉后可避免Firefox的域验证错误
内容的提问来源于stack exchange,提问作者Cat Hariss
相关产品推荐
相关产品推荐

