如何使用 Python + Selenium WebDriver 保存和加载 cookie

2024-12-04 08:56:00
admin
原创
161
摘要:问题描述:如何将 Python 的 Selenium WebDriver 中的所有 cookie 保存到 .txt 文件中,然后稍后加载它们?文档没有过多提及 getCookies 函数。解决方案 1:您可以使用 pickle 将当前 cookie 保存为 Python 对象。例如:import pickle...

问题描述:

如何将 Python 的 Selenium WebDriver 中的所有 cookie 保存到 .txt 文件中,然后稍后加载它们?

文档没有过多提及 getCookies 函数。


解决方案 1:

您可以使用 pickle 将当前 cookie 保存为 Python 对象。例如:

import pickle
import selenium.webdriver

driver = selenium.webdriver.Firefox()
driver.get("http://www.google.com")
pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb"))

稍后再将它们添加回来:

import pickle
import selenium.webdriver

driver = selenium.webdriver.Firefox()
driver.get("http://www.google.com")
cookies = pickle.load(open("cookies.pkl", "rb"))
for cookie in cookies:
    driver.add_cookie(cookie)

解决方案 2:

当您需要会话间 cookie 时,还有另一种方法。使用 Chrome 选项 user-data-dir 以便将文件夹用作配置文件。我运行:

# You need to: from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium")
driver = webdriver.Chrome(options=chrome_options)
#for selenium 4.15.2 options instead of chrome_options
#driver = webdriver.Chrome(options=chrome_options) 
driver.get("www.google.com")

您可以在此处进行检查人机交互的登录。我执行此操作,然后每次使用该文件夹启动 Webdriver 时,我现在需要的 cookie 都在那里。您还可以手动安装扩展程序并在每个会话中安装它们。

第二次运行时,所有的 cookie 都在那里:

# You need to: from selenium.webdriver.chrome.options import Options    
chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(options=chrome_options)
#for selenium 4.15.2 options instead of chrome_options
#driver = webdriver.Chrome(options=chrome_options) 
driver.get("www.google.com") # Now you can see the cookies, the settings, extensions, etc., and the logins done in the previous session are present here. 

优点是您可以使用具有不同设置和 cookie 的多个文件夹,而无需加载扩展、卸载 cookie、安装和卸载扩展、更改设置、通过代码更改登录,从而不会中断程序的逻辑等。

此外,这比通过代码完成所有操作要快得多。

解决方案 3:

请记住,您只能为当前域添加 cookie。

如果你想为你的 Google 帐户添加 Cookie,请执行以下操作

browser.get('http://google.com')
for cookie in cookies:
    browser.add_cookie(cookie)

解决方案 4:

只需对Roel Van de Paar 编写的代码进行轻微修改,所有功劳都归于他。我在 Windows 中使用它,它运行良好,既可以设置也可以添加 cookie:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('chromedriver.exe',options=chrome_options)
driver.get('https://web.whatsapp.com')  # Already authenticated
time.sleep(30)

解决方案 5:

根据Eduard Florinescu 的回答,但添加了较新的代码和缺失的导入:

$ cat work-auth.py
#!/usr/bin/python3

# Setup:
# sudo apt-get install chromium-chromedriver
# sudo -H python3 -m pip install selenium

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('/usr/bin/chromedriver',options=chrome_options)
chrome_options.add_argument("user-data-dir=chrome-data")
driver.get('https://www.somedomainthatrequireslogin.com')
time.sleep(30)  # Time to enter credentials
driver.quit()

$ cat work.py
#!/usr/bin/python3

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument("--user-data-dir=chrome-data")
driver = webdriver.Chrome('/usr/bin/chromedriver',options=chrome_options)
driver.get('https://www.somedomainthatrequireslogin.com')  # Already authenticated
time.sleep(10)
driver.quit()

解决方案 6:

这是为 Firefox 保存配置文件目录的解决方案。

与最佳答案driver.get_cookies()相比,此解决方案的优势
在于,除了 cookie 之外,还存储了其他数据(localStorage、IndexedDB),这很有用,因为一些网站使用它们来持久会话。

使用 Chrome 的解决方案user-data-dir也与localStorage此类似,但它使用的是 Chrome 而不是 Firefox。

它在 Linux 上进行了测试。


理想情况下,最好一开始就不要复制目录,但这很难,请参阅

  • 如何防止 Selenium 3.0(Geckodriver)创建临时 Firefox 配置文件?

  • 如何在 Selenium Webdriver 中使用现有的配置文件?

  • 无法使用 C# 在 Selenium WebDriver 中使用现有的 Firefox 配置文件(与下面的解决方案类似)


简短版本:

  • 保存配置文件

driver.execute_script("window.close()")
time.sleep(0.5)
currentProfilePath = driver.capabilities["moz:profile"]
profileStoragePath = "/tmp/abc"
shutil.copytree(currentProfilePath, profileStoragePath,
                ignore_dangling_symlinks=True
                )
  • 加载配置文件

driver = Firefox(executable_path="geckodriver-v0.28.0-linux64",
                 firefox_profile=FirefoxProfile(profileStoragePath)
                )

长版本(证明其有效并有大量解释 - 请参阅代码中的注释)

该代码用于localStorage演示,但它也适用于 cookie。

#initial imports

from selenium.webdriver import Firefox, FirefoxProfile

import shutil
import os.path
import time

# Create a new profile

driver = Firefox(executable_path="geckodriver-v0.28.0-linux64",
                  # * I'm using this particular version. If yours is
                  # named "geckodriver" and placed in system PATH
                  # then this is not necessary
                )

# Navigate to an arbitrary page and set some local storage
driver.get("https://DuckDuckGo.com")
assert driver.execute_script(r"""{
        const tmp = localStorage.a; localStorage.a="1";
        return [tmp, localStorage.a]
    }""") == [None, "1"]

# Make sure that the browser writes the data to profile directory.
# Choose one of the below methods
if 0:
    # Wait for some time for Firefox to flush the local storage to disk.
    # It's a long time. I tried 3 seconds and it doesn't work.
    time.sleep(10)

elif 1:
    # Alternatively:
    driver.execute_script("window.close()")
    # NOTE: It might not work if there are multiple windows!

    # Wait for a bit for the browser to clean up
    # (shutil.copytree might throw some weird error if the source directory changes while copying)
    time.sleep(0.5)

else:
    pass
    # I haven't been able to find any other, more elegant way.
    #`close()` and `quit()` both delete the profile directory


# Copy the profile directory (must be done BEFORE driver.quit()!)
currentProfilePath = driver.capabilities["moz:profile"]
assert os.path.isdir(currentProfilePath)
profileStoragePath = "/tmp/abc"
try:
    shutil.rmtree(profileStoragePath)
except FileNotFoundError:
    pass

shutil.copytree(currentProfilePath, profileStoragePath,
                ignore_dangling_symlinks=True # There's a lock file in the
                                              # profile directory that symlinks
                                              # to some IP address + port
               )

driver.quit()
assert not os.path.isdir(currentProfilePath)
# Selenium cleans up properly if driver.quit() is called,
# but not necessarily if the object is destructed


# Now reopen it with the old profile

driver=Firefox(executable_path="geckodriver-v0.28.0-linux64",
               firefox_profile=FirefoxProfile(profileStoragePath)
              )

# Note that the profile directory is **copied** -- see FirefoxProfile documentation
assert driver.profile.path!=profileStoragePath
assert driver.capabilities["moz:profile"]!=profileStoragePath

# Confusingly...
assert driver.profile.path!=driver.capabilities["moz:profile"]
# And only the latter is updated.
# To save it again, use the same method as previously mentioned

# Check the data is still there

driver.get("https://DuckDuckGo.com")

data = driver.execute_script(r"""return localStorage.a""")
assert data=="1", data

driver.quit()

assert not os.path.isdir(driver.capabilities["moz:profile"])
assert not os.path.isdir(driver.profile.path)

无效的方法:

  • 初始化Firefox(capabilities={"moz:profile": "/path/to/directory"})——驱动程序将无法连接。

  • options=Options(); options.add_argument("profile"); options.add_argument("/path/to/directory"); Firefox(options=options)—— 与上相同。

解决方案 7:

尝试这个方法:

import pickle
from selenium import webdriver
driver = webdriver.Chrome(executable_path="chromedriver.exe")
URL = "SITE URL"
driver.get(URL)
sleep(10)
if os.path.exists('cookies.pkl'):
    cookies = pickle.load(open("cookies.pkl", "rb"))
    for cookie in cookies:
        driver.add_cookie(cookie)
    driver.refresh()
    sleep(5)
# check if still need login
# if yes:
# write login code
# when login success save cookies using
pickle.dump(driver.get_cookies(), open("cookies.pkl", "wb"))

解决方案 8:

这是我在 Windows 中使用的代码。它有效。

for item in COOKIES.split(';'):
    name,value = item.split('=', 1)
    name=name.replace(' ', '').replace('
', '').replace('
', '')
    value = value.replace(' ', '').replace('
', '').replace('
', '')
    cookie_dict={
            'name':name,
            'value':value,
            "domain": "",  # Google Chrome
            "expires": "",
            'path': '/',
            'httpOnly': False,
            'HostOnly': False,
            'Secure': False
        }
    self.driver_.add_cookie(cookie_dict)

解决方案 9:

使用此代码存储任何网站(如谷歌、脸书等)的登录会话

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import undetected_chromedriver as uc
options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:/Users/salee/AppData/Local/Google/Chrome/User Data/Profile 1")
browser = uc.Chrome(use_subprocess=True,Options=options)

解决方案 10:

就我的情况而言,可以接受的答案几乎已经存在了。

对于那些无法通过上述方式找到答案的人,欢迎尝试我的方法。

在开始编码之前,请确保该网站使用 cookie 进行身份验证。

步:

  1. 打开您的浏览器(我在这里使用 Chrome),登录您的网站。

  2. 请访问此网站以了解如何检查 cookie 的值

  3. 以隐身模式打开另一个浏览器并访问您的网站(此时,您的网站仍应提示您登录页面)

  4. 尝试使用第一个浏览器的 cookies 值相应地修改 cookies 值(您的第一个浏览器必须通过您的网站的身份验证)

  5. 刷新隐身模式浏览器,它应该会绕过登录页面

上述步骤是我用来确保添加的 cookie 能够对我的网站进行身份验证的方法。

现在是编码部分,它几乎与接受的答案相同。对于我来说,接受的答案的唯一问题是我最终得到的 cookie 数量增加了一倍。

pickle.dump 部分对我来说没有问题,所以我直接进入添加 cookie 部分。

import pickle
import selenium.webdriver

driver = selenium.webdriver.Chrome()
driver.get("http://your.website.com")

cookies = pickle.load(open("cookies.pkl", "rb"))
# the reason that I delete the cookies is because I found duplicated cookies by inspect the cookies with browser like step 2
driver.delete_all_cookies()

for cookie in cookies:
    driver.add_cookie(cookie)

driver.refresh()

您可以使用步骤 2 来检查使用代码添加的 cookie 是否正常工作。

希望有帮助。

解决方案 11:

这里的大多数答案都是关于腌制饼干的,我试过了,但没有正常工作。您可以简单地将 cookies() 响应存储在文本文件中,并在需要时加载它。

访问网站并登录或进行其他与 cookie 相关的活动

from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://google.com")

存储 cookie

with open("cookies.txt", "r") as f:
    cookies = eval(f.read())

要测试它,请关闭并重新打开驱动程序并加载 cookie

driver.quit()
driver = webdriver.Chrome()
driver.get("https://google.com")

加载 cookie

for cookie in cookies:
    driver.add_cookie(cookie)

刷新以反映更改

driver.refresh()

解决方案 12:

这里的所有答案都不能解决我的问题,所以我想我会分享我发现的最终成为解决方案的方法。

当然,您需要首先保存您的会话 cookie:

def get_cookies(self):
    cookies = {}
    selenium_cookies = self.driver.get_cookies()
    for cookie in selenium_cookies:
        cookies[cookie['name']] = cookie['value']
    return cookies
def dump_cookies(self, output_file_path: str):
    cookies = self.get_cookies()
    with open(output_file_path, 'w') as f:
        json.dump(cookies, f)
    self.debug_print(f'Saved cookies to: {output_file_path}')

通常只需加载这些 cookie 然后刷新页面就足够了:

def load_cookies(self, path):
    with open(path) as f:
        cookies = json.load(f)
    for key, value in cookies.items():
        self.driver.add_cookie({'name': key, 'value': value})

但就我而言,我还必须保存本地存储...:

def save_storage(self):
    local_storage = self.driver.execute_script(
        "var items = {}, ls = window.localStorage; for (var i = 0; i < ls.length; i++)  items[ls.key(i)] = ls.getItem(ls.key(i)); return items;")
    with open("data/local_storage.json", "w") as f:
        json.dump(local_storage, f)

然后在新的会话中加载该存储:

def load_storage(self):
    with open("data/local_storage.json", "r") as f:
        local_storage = json.load(f)
    for key, value in local_storage.items():
        self.driver.execute_script(f"window.localStorage.setItem('{key}', '{value}')")

快速回顾:

  1. 加载 selenium,导航到需要身份验证的站点。

  2. 运行dump_cookies并将save_storage会话数据保存到磁盘。

  3. 关闭当前会话

  4. 加载一个新会话,再次导航到同一站点。

  5. 运行load_cookies然后刷新页面load_storagedriver.refresh()

  6. 希望您现在已登录。如果没有,请 driver.delete_all_cookies()在加载 cookie 之前尝试运行,因为这将清除网站在您加载登录 cookie 之前可能设置的任何 cookie。这对我来说没有必要。

解决方案 13:

对于 OS = Mac OS Ventura;Python = 3.10.4;SE = 4.12.0,请查看我最近测试过的连接到 Edge 会话和配置文件

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用