使用 Selenium Firefox Webdriver 在 Python3 中的第一个请求之前添加 cookie

问题描述 投票:0回答:1

我有一个 PKI 身份验证网站,因此打开页面时的第一件事就是要求输入 PIN 码,这样我就无法在加载页面之前设置已保存的 cookie。

我在 chrome 驱动程序这里看到了类似的解决方案,但 Firefox Webdriver 对象没有execute_cdp_cmd。另外,当尝试加载 cookie 而不加载页面,并且根本不尝试使用execute_cdp_cmd 时,我收到以下错误,正如预期的那样,只是引用了 chrome 而不是 firefox。

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

我的代码如下:

import time
import os
import pickle
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

driver = webdriver.Firefox("C:\\Users\\myuser\\PycharmProjects\\myproject\\")
cookie_path = "cookies.pkl"


def get_page():
    # driver.get(f"https://mypkiaythenticationpage.com")

    if not os.path.isfile(cookie_path):
        print("Cookie File not found, generating new one")
        pickle.dump(driver.get_cookies(), open("cookies.pkl","wb"))
    else:
        # driver.delete_all_cookies()
        # driver.execute_cdp_cmd('Network.enable', {})
        cookies = pickle.load(open("cookies.pkl", "rb"))
        for cookie in cookies:
            driver.add_cookie(cookie)
        print("Loading cookie ...")
    driver.get(f"https://mypkiaythenticationpage.com")

def save_last_cookie_state():
    print("Saving last cookie state ...")
    pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb"))


#
if __name__ == '__main__':
    get_page()
    driver.get(f"https://mypkiaythenticationpage.com")
    save_last_cookie_state()
python-3.x selenium-firefoxdriver
1个回答
0
投票

这可以通过分配给

cookies.sqlite
的配置文件中的
webdriver
数据库来完成。
cookies.sqlite
可以通过 Selenium cookie 生成,如下所示:

from contextlib import closing
import os
import sqlite3
from typing import Any, Mapping
from collections.abc import Sequence

# Generated via `sqlite3 -readonly /path/to/fxprofile/cookies.sqlite ".schema"`.
# See http://fileformats.archiveteam.org/wiki/Firefox_cookie_database
SQL_STATEMENT_CREATE_TABLE = r"""
CREATE TABLE
moz_cookies (
    id INTEGER PRIMARY KEY,
    originAttributes TEXT NOT NULL DEFAULT '',
    name TEXT,
    value TEXT,
    host TEXT,
    path TEXT,
    expiry INTEGER,
    lastAccessed INTEGER,
    creationTime INTEGER,
    isSecure INTEGER,
    isHttpOnly INTEGER,
    inBrowserElement INTEGER DEFAULT 0,
    sameSite INTEGER DEFAULT 0,
    rawSameSite INTEGER DEFAULT 0,
    schemeMap INTEGER DEFAULT 0,
    CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)
)
"""

SQL_STATEMENT_INSERT_COOKIE = r"""
INSERT INTO
  moz_cookies (
    name,
    value,
    host,
    path,
    expiry,
    lastAccessed,
    creationTime,
    isSecure,
    isHttpOnly
  )
VALUES (
    :name,
    :value,
    :domain,
    :path,
    :expiry,
    :access_time,
    :creation_time,
    :secure,
    :httponly
  );
"""


def generate_cookies_db(
    cookies: Sequence[Mapping[str, Any]],
    access_time: int,
    creation_time: int,
    db_path: str | os.PathLike,
) -> None:
    with closing(sqlite3.connect(db_path)) as connection:
        with closing(connection.cursor()) as cursor:
            cursor.execute(SQL_STATEMENT_CREATE_TABLE)
            for cookie in cookies:
                values = {
                    "access_time": access_time,
                    "creation_time": creation_time,
                    "domain": cookie.get("domain"),
                    "expiry": cookie.get("expiry"),
                    "httponly": cookie.get("httpOnly", False),
                    "name": cookie["name"],
                    "path": cookie.get("path"),
                    "secure": cookie.get("secure", False),
                    "value": cookie["value"],
                }
                cursor.execute(SQL_STATEMENT_INSERT_COOKIE, values)
        connection.commit()

或者,您可以直接使用

sqlite3
从现有配置文件中进行过滤:

$ sqlite3 -readonly /path/to/fxprofile/cookies.sqlite ".mode insert moz_cookies" ".schema" "SELECT * FROM moz_cookies WHERE host LIKE '%.example.com'" | sqlite3 ./cookies.sqlite

请注意,当 Firefox 运行时,

cookies.sqlite
将被锁定。

然后,将生成的

cookies.sqlite
复制到
webdriver
使用的配置文件:

$ mkdir ./profile_template
$ mv ./cookies.sqlite ./profile_template
from selenium import webdriver
from selenium.webdriver.firefox.options import Options

options = Options()
options.profile = webdriver.FirefoxProfile("./profiletemplate")

with webdriver.Firefox(options=options) as session:
    session.get("https://example.com")

此目录将被 Selenium 克隆并视为只读,因为

webdriver.FirefoxProfile
不会持久化

© www.soinside.com 2019 - 2024. All rights reserved.