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

Aar*_*ker 78 python selenium webdriver

如何将Python的Selenium WebDriver中的所有cookie保存到txt文件中,然后再加载它们?该文档没有说明getCookies函数的任何内容.

Ali*_*fee 141

您可以使用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"))
Run Code Online (Sandbox Code Playgroud)

然后将它们添加回来:

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)
Run Code Online (Sandbox Code Playgroud)

  • 我对此有疑问。它工作正常,但是当我再次尝试“drive.add_cookie”时,我收到一条错误消息,指出“expiry”密钥无效。我在 Mac 操作系统上使用 chromedriver (7认同)
  • 这样我就无法使用之前保存的 cookie 再次登录。 (3认同)

Edu*_*scu 29

如果您需要在会话之间使用Cookie,还有其他方法可以执行此操作,请使用Chrome选项user-data-dir将文件夹用作配置文件,我运行:

chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(chrome_options=chrome_options)
driver.get("www.google.com")
Run Code Online (Sandbox Code Playgroud)

您可以在这里执行检查人工交互的登录,我这样做,然后我现在需要的cookie,每次我启动Webdriver与该文件夹一切都在那里.您也可以手动安装扩展程序并在每个会话中使用它们.Secon我跑的时间,所有的饼干都在那里:

chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium") 
driver = webdriver.Chrome(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. 
Run Code Online (Sandbox Code Playgroud)

优点是您可以使用具有不同设置和cookie的多个文件夹,无需加载的扩展,卸载cookie,安装和卸载扩展,更改设置,通过代码更改登录,因此无法使程序的逻辑中断,等等,这比通过代码完成这一切更快.

  • @Dan你需要:`from selenium.webdriver.chrome.options import Options` (6认同)
  • `chrome_options = Options()` 给我`名称'选项'未定义` ...? (4认同)
  • 这是我处理Google登录名时最好的解决方案。在某个时候,我的开发使用被标记为可疑活动。 (3认同)
  • 抱歉,在使用解决方案之前已对其进行了标记。现在,我保持登录状态,因此没有可疑活动。 (3认同)
  • @ p1g1n在使用此解决方案之前或之后被标记 (2认同)
  • 该代码有点过时,并且缺少必需的导入。我将发布一个新答案。 (2认同)
  • 虽然似乎不适用于无头模式,但可以! (2认同)

小智 27

请记住,您只能为CURRENT域添加cookie.如果你想添加你的Goolge帐户.

browser.get('http://google.com')
for cookie in cookies:
    browser.add_cookie(cookie)
Run Code Online (Sandbox Code Playgroud)

  • @MauricioCortazar它没有提到域名要求,这就是我所指的 (3认同)
  • 这应该在他们的文档中:( (2认同)
  • @Tjorriemorrie 那是基本人,cookie 只存储在域中,甚至不允许子域 (2认同)
  • 此评论似乎与使用来自根域的 cookie 的多个域相关。例如,google.com 可以是根域,而 Google 拥有的另一个域或子域可以使用相同的 cookie。由于这个(和其他原因),我更喜欢 @Eduard Florinescu 的解决方案,因为它不需要在加载 cookie 之前使用 browser.get,它们就在数据目录中。在加载 cookie 文件之前,这里似乎需要额外的 browser.get(根据此评论),但没有对其进行测试。 (2认同)

小智 20

只是对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)
Run Code Online (Sandbox Code Playgroud)

  • 为我工作,尽管我必须在“user-data-dir”上设置特定路径(我使用“os.getcwd()”)。 (2认同)

Roe*_*aar 6

基于@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()
Run Code Online (Sandbox Code Playgroud)

  • 泡菜的东西对我不起作用。(这是我第二次尝试使用它。)因此,我使用了您的方法,但这种方法最初对我也不起作用。我必须进行的更改:由于https://github.com/theintern/intern/issues/878中记录的问题,我不得不键入chrome_options.add_argument('no-sandbox'),并且我必须创建用户数据- dir在我的Windows 10环境中的完整路径。 (2认同)

use*_*729 6

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

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

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

它在 Linux 上进行了测试。


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


简洁版本:

  • 保存配置文件
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
                )
Run Code Online (Sandbox Code Playgroud)
  • 加载配置文件
driver = Firefox(executable_path="geckodriver-v0.28.0-linux64",
                 firefox_profile=FirefoxProfile(profileStoragePath)
                )
Run Code Online (Sandbox Code Playgroud)

长版本(带有其工作原理的演示和大量解释——请参阅代码中的注释)

该代码用于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)
Run Code Online (Sandbox Code Playgroud)

什么不起作用:

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


归档时间:

查看次数:

88883 次

最近记录:

6 年 前