如何使用 Python3、Selenium Chrome WebDriver 在第一次请求之前预加载 cookie?

Ale*_*scu 13 cookies selenium google-chrome webdriver python-3.x

add_cookie()在对域stackoverflow.comget()上的页面进行实际请求之前,是否可以在 Selenium Chrome WebDriver 中添加用于域的 cookie,例如stackoverflow.com

尝试时:

driver.webdriver.add_cookie({'name' : 'testcookie', 'value' : 'testvalue', 'domain' : 'stackoverflow.com'})
driver.webdriver.get('https://stackoverflow.com/')
Run Code Online (Sandbox Code Playgroud)

我得到“您只能为当前域设置 cookie ”。

我想说我看到并尝试了一些避免问题而不是解决问题的解决方案,例如预先访问域上的 404 页面以在 Selenium 中创建“域槽”,然后再向其添加 cookie,但是虽然这些解决方案允许添加他们仍然需要在未设置任何 cookie 的情况下提出一项额外请求并与网站联系。

在处理 CAPTCHA 系统和一些非常具体的 WAF 时,这是一个问题,这些系统在连续看到一个不带 cookie 的请求,然后又看到另一个带 cookie 的请求时会皱起眉头,而这个请求只能在完成登录过程后才被说出。

Ale*_*scu 24

从 Chrome 64 开始,我们现在可以访问 Chrome DevTools Protocol v1.3,它允许通过 Network.setCookie 方法将 cookie 设置到任何域,从而无需额外的 get 调用来预先设置域。

例如Python3

import os.path
import pickle
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def save_cookies():
    print("Saving cookies in " + selenium_cookie_file)
    pickle.dump(driver.get_cookies() , open(selenium_cookie_file,"wb"))

def load_cookies():
    if os.path.exists(selenium_cookie_file) and os.path.isfile(selenium_cookie_file):
        print("Loading cookies from " + selenium_cookie_file)
        cookies = pickle.load(open(selenium_cookie_file, "rb"))

        # Enables network tracking so we may use Network.setCookie method
        driver.execute_cdp_cmd('Network.enable', {})

        # Iterate through pickle dict and add all the cookies
        for cookie in cookies:
            # Fix issue Chrome exports 'expiry' key but expects 'expire' on import
            if 'expiry' in cookie:
                cookie['expires'] = cookie['expiry']
                del cookie['expiry']

            # Replace domain 'apple.com' with 'microsoft.com' cookies
            cookie['domain'] = cookie['domain'].replace('apple.com', 'microsoft.com')

            # Set the actual cookie
            driver.execute_cdp_cmd('Network.setCookie', cookie)

        # Disable network tracking
        driver.execute_cdp_cmd('Network.disable', {})
        return 1

    print("Cookie file " + selenium_cookie_file + " does not exist.")
    return 0

def pretty_print(pdict):
    for p in pdict:
        print(str(p))
    print('',end = "\n\n")


# Minimal settings
selenium_cookie_file = '/home/selenium/test.txt'

browser_options = Options()
browser_options.add_argument("--headless")

# Open a driver, get a page, save cookies
driver = webdriver.Chrome(chrome_options=browser_options)
driver.get('https://apple.com/')
save_cookies()
pretty_print(driver.get_cookies())


# Rewrite driver with a new one, load and set cookies before any requests
driver = webdriver.Chrome(chrome_options=browser_options)
load_cookies()
driver.get('https://microsoft.com')
pretty_print(driver.get_cookies())
Run Code Online (Sandbox Code Playgroud)

您将在上面看到,我们通过一个请求从域“apple.com”获取 cookie,并在实际向“microsoft.com”发出请求之前为对域“microsoft.com”的第二个请求加载并设置它们。

只要将变量设置selenium_cookie_file为有效的可写文件路径,代码就会经过测试并正常工作。

  • 只是想说一声谢谢!我一直在寻找如何在驱动程序调用之前预加载 cookie 的方法,并且此解决方案已经起作用!不幸的是,其他建议(例如导航到 404 或图像)对我来说不起作用,因为整个网站受 MFA 保护,并且一旦网站加载就会触发 cookie,而我现在设法通过此解决方案实现这一点。PS:除了 selenium_cookie_file 变量必须是有效路径之外,还必须根据每个人自己的需要编辑替换域部分:-) (3认同)
  • 我在这里为此打开了一个单独的主题:/sf/ask/5226681071/ (3认同)
  • 这在 Firefox 上不起作用,有类似的东西吗? (2认同)