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

如何将 Python 的 SeleniumWebDriver 中的所有 cookie 保存到一个. txt 文件中,然后在以后加载它们?

文档中没有提到任何关于 getCookies 函数的内容。

256857 次浏览

您可以使用 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)

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

如果你想为你的谷歌账户添加一个 cookie,那就这么做吧

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

当您需要从一个会话到另一个会话的 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(chrome_options=chrome_options)
driver.get("www.google.com")

在这里,您可以进行检查人机交互的登录。我这样做,然后饼干,我需要现在每次我开始与该文件夹的网络驱动程序一切都在那里。您还可以手动安装扩展,并在每个会话中使用它们。

我第二次跑的时候,所有的饼干都在那儿了:

# You need to: from selenium.webdriver.chrome.options import Options
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.

优点是你可以使用不同的设置和 cookie 的多个文件夹,扩展而不需要加载,卸载 cookies,安装和卸载扩展,更改设置,通过代码更改登录,因此没有办法有程序中断的逻辑,等等。

而且,这比通过代码完成所有工作要快。

基于 爱德华 · 弗洛里内斯库的回答,但添加了更新的代码和缺少的导入:

$ 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()

只是对代码 作者是罗尔 · 范德帕尔做了一点小小的修改,因为所有的功劳都归于他。我在 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)

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

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

理想情况下,最好不要首先复制目录,但这非常困难,请参见

还有

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

这是一个为 Firefox 保存配置文件目录的解决方案(类似于 Chrome 中的 user-data-dir(用户数据目录))(它涉及到手动复制目录。我找不到其他办法) :

它是在 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
)
  • 加载配置文件
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)——与上面相同。

试试这个方法:

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"))

使用此代码存储任何网站如谷歌 Facebook 等登录会话

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)