如何使用 Python + Selenium WebDriver 保存和加载 cookie
- 2024-12-04 08:56:00
- admin 原创
- 161
问题描述:
如何将 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 进行身份验证。
步:
打开您的浏览器(我在这里使用 Chrome),登录您的网站。
请访问此网站以了解如何检查 cookie 的值
以隐身模式打开另一个浏览器并访问您的网站(此时,您的网站仍应提示您登录页面)
尝试使用第一个浏览器的 cookies 值相应地修改 cookies 值(您的第一个浏览器必须通过您的网站的身份验证)
刷新隐身模式浏览器,它应该会绕过登录页面
上述步骤是我用来确保添加的 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}')")
快速回顾:
加载 selenium,导航到需要身份验证的站点。
运行
dump_cookies
并将save_storage
会话数据保存到磁盘。关闭当前会话
加载一个新会话,再次导航到同一站点。
运行
load_cookies
然后刷新页面load_storage
。driver.refresh()
希望您现在已登录。如果没有,请
driver.delete_all_cookies()
在加载 cookie 之前尝试运行,因为这将清除网站在您加载登录 cookie 之前可能设置的任何 cookie。这对我来说没有必要。
解决方案 13:
对于 OS = Mac OS Ventura;Python = 3.10.4;SE = 4.12.0,请查看我最近测试过的连接到 Edge 会话和配置文件