Как сохранить и загрузить куки с помощью Python + Selenium WebDriver
Как я могу сохранить все куки в Python Selenium WebDriver в текстовый файл, а затем загрузить их позже? Документация ничего не говорит о функции getCookies.
14 ответов
Вы можете сохранить текущие куки как объект python, используя pickle. Например:
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 от сеанса к сеансу, есть другой способ сделать это, используя параметры 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")
Здесь вы можете выполнить вход в систему, которая проверяет взаимодействие с человеком, я делаю это, а затем файлы cookie, которые мне нужны теперь каждый раз, когда я запускаю Webdriver с этой папкой, там все есть. Вы также можете вручную установить расширения и использовать их в каждом сеансе. В следующий раз я запускаю все куки:
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 and the logins done in the previous session are present here
Преимущество заключается в том, что вы можете использовать несколько папок с различными настройками и файлами cookie, расширениями без необходимости загружать, выгружать файлы cookie, устанавливать и удалять расширения, изменять настройки, изменять логины с помощью кода и, таким образом, не иметь логики прерывания программы, и т. д. Кроме того, это быстрее, чем с помощью кода.
Помните, что вы можете добавить cookie только для ТЕКУЩЕГО домена. если вы хотите добавить свой аккаунт Goolge.
Делать
browser.get('http://google.com')
for cookie in cookies:
browser.add_cookie(cookie)
Просто небольшое изменение кода, написанного @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)
На основе ответа @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()
Это решение, которое сохраняет каталог профиля для Firefox (аналогично
user-data-dir
(каталог пользовательских данных) в Chrome) (это включает в себя ручное копирование каталога. Другого способа найти не удалось):
Тестировалась на 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)
- то же, что и выше.
Это код, который я использовал в 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)
Попробуйте этот метод:
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"))
Используйте этот код для сохранения сеанса входа на любой веб-сайт, такой как google 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)
Для моего случая принятый ответ почти есть.
Для людей, которым не повезло с ответами выше, вы можете попробовать мой способ.
Прежде чем приступить к программированию, убедитесь, что веб-сайт использует файлы cookie для аутентификации.
Шаг:
- Откройте браузер (здесь я использую Chrome), войдите на свой сайт.
- Перейдите на этот веб-сайт , чтобы узнать, как проверить значение файлов cookie.
- Откройте другой браузер в режиме инкогнито и перейдите на свой сайт (на этом этапе ваш сайт все еще должен предлагать вам страницу входа)
- Попробуйте изменить значение куки с соответствующим значением куки первого браузера (ваш первый браузер должен аутентифицироваться на вашем веб-сайте)
- Обновите браузер в режиме инкогнито, он должен пройти через страницу входа
Вышеуказанные шаги — это то, как я использовал, чтобы убедиться, что добавление файлов 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, которые вы добавляете с помощью кода.
Надеюсь, поможет.
Большинство ответов здесь касаются маринования печенья. Я пробовал, но оно не сработало должным образом. вы можете просто сохранить ответ cookie() в текстовом файле и загружать его, когда он вам понадобится.
Перейдите на веб-сайт и войдите в систему или выполните другие действия, связанные с файлами 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()
Ни один из ответов здесь не решил мою проблему, поэтому я решил поделиться методом, который я обнаружил, и который в конечном итоге стал моим решением.
Конечно, вам необходимо сначала сохранить файлы 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}')")
Краткое резюме:
- Загрузите селен, перейдите на свой сайт, требующий авторизации.
- Бегать
dump_cookies
иsave_storage
для сохранения данных сеанса на диск. - Закрыть текущий сеанс
- Загрузите новый сеанс, снова перейдите на тот же сайт.
- Бегать
load_cookies
иload_storage
а потомdriver.refresh()
чтобы обновить страницу. - Надеюсь, теперь вы вошли в систему. Если нет, попробуйте запустить
driver.delete_all_cookies()
перед загрузкой файлов cookie, так как при этом будут удалены все файлы cookie, которые сайт мог установить до загрузки файлов cookie для входа. Мне в этом не было необходимости.
Для ОС = Mac OS Ventura; Питон = 3.10.4; SE = 4.12.0, посмотрите это, которое мне удалось протестировать совсем недавно. Подключение к пограничному сеансу и профилю.
Моя ОС - Windows 10, а версия для Chrome - 75.0.3770.100. Я пробовал решение "user-data-dir", не сработало. попробуйте решение @ Eric Klien тоже не удается. наконец, я делаю настройку Chrome, как на картинке, она работает! но она не работает на сервере Windows 2012.
установка