Last active
February 7, 2024 23:17
-
-
Save sh4dowb/0054e4b25bf81bccca6f9e622c5cb160 to your computer and use it in GitHub Desktop.
workaround for selenium to save the goddamn session / profile completely on firefox / geckodriver --- selenium firefox geckodriver persistent profile
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Selenium does not use the given profile, but copies it, and uses a temporary profile. | |
# As a result, new cookies and sessions etc. are not saved. | |
# To fix it, we get the actual profile firefox is using, kill firefox manually so geckodriver | |
# doesn't delete profile data. Copying the profile when it's being used is generally not a good idea. | |
# After killing firefox profile and databases are unlocked, we copy the "temporary" profile | |
# to our old profile. | |
# | |
# driver.profile doesn't provide the actual temporary profile, but another copy of it. And firefox | |
# does not use that one. that's why I got it from process list. | |
# | |
# Note that it works for Linux, you can implement process things to Windows easily I guess | |
from selenium import webdriver | |
from selenium.webdriver.firefox.options import Options | |
from selenium.webdriver import Firefox | |
import random, psutil, shutil, os, time | |
# can be a new folder | |
profile_path = "/tmp/persistent_profile" | |
if not os.path.isdir(profile_path): | |
os.mkdir(profile_path) | |
firefox_profile = webdriver.FirefoxProfile(profile_path) | |
options = Options() | |
options.profile = firefox_profile | |
# add a random thing so we can distinguish the firefox process | |
distinguishkey = "-persistentprofileworkaround"+str(random.randint(111111,999999)) | |
options.add_argument(distinguishkey) | |
driver = webdriver.Firefox(options=options, executable_path="geckodriver") | |
# do web stuff here | |
#driver.get("http://localhost/cookie.php") | |
#time.sleep(1) | |
#driver.get("http://localhost/cookie.php") | |
#time.sleep(1) | |
#driver.get("http://localhost/cookie.php") | |
for pid in psutil.pids(): | |
try: | |
cmdline = open("/proc/"+str(pid)+"/cmdline", "r").read() | |
if distinguishkey in cmdline: | |
profile = cmdline.split('-profile')[1].split(' ')[0].replace('\x00', '') | |
break | |
except: | |
pass | |
else: | |
print('cannot find firefox pid') | |
exit() | |
psutil.Process(pid).kill() # kill firefox (nicely) and unlock profile lock | |
if os.path.isdir(profile_path): | |
shutil.rmtree(profile_path) | |
shutil.copytree(profile, profile_path, symlinks=True) # copy the new profile to profile_path, don't resolve "lock" symlink | |
try: | |
driver.quit() # will throw an error because we killed firefox | |
except: | |
pass | |
# cleanup | |
if os.path.isdir(profile): | |
shutil.rmtree(profile) | |
if os.path.isdir(driver.profile.tempfolder): | |
shutil.rmtree(driver.profile.tempfolder) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment