Skip to content

Instantly share code, notes, and snippets.

@sh4dowb
Last active February 7, 2024 23:17
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sh4dowb/0054e4b25bf81bccca6f9e622c5cb160 to your computer and use it in GitHub Desktop.
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
# 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