180 votes

Comment enregistrer et charger des cookies en utilisant Python + Selenium WebDriver

Comment puis-je enregistrer tous les cookies dans Selenium WebDriver de Python dans un fichier .txt, puis les charger plus tard ?

La documentation ne dit pas grand-chose sur la fonction getCookies.

4voto

user202729 Points 1154

Idéalement, il serait préférable de ne pas copier le répertoire en premier lieu, mais c'est très difficile, cf.

Aussi


Il s'agit d'une solution qui permet de sauvegarder le répertoire de profil pour Firefox (similaire à la méthode user-data-dir (répertoire des données utilisateur) dans Chrome) (cela implique de copier manuellement le répertoire autour. Je n'ai pas été en mesure de trouver un autre moyen) :

Il a été testé sur Linux.


Version courte :

  • Pour enregistrer le profil

    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 )

  • Pour charger le profil

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


Version longue (avec démonstration que cela fonctionne et beaucoup d'explications -- voir les commentaires dans le code)

Le code utilise localStorage pour la démonstration, mais cela fonctionne aussi avec les cookies.

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

Ce qui ne marche pas :

  • Initialiser Firefox(capabilities={"moz:profile": "/path/to/directory"}) -- le pilote ne pourra pas se connecter.
  • options=Options(); options.add_argument("profile"); options.add_argument("/path/to/directory"); Firefox(options=options) -- même chose que ci-dessus.

2voto

yong you Points 21

Voici le code que j'ai utilisé dans Windows. Il fonctionne.

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)

1voto

Essayez cette méthode :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X