Python Selenium Cookies for Login Session Automation
Save Selenium cookies after login, restore them in later runs, and handle expiry, domain restrictions, and re-authentication.
Re-authenticating on every Selenium run is slow and can trigger anti-bot measures. Storing and reusing cookies is the standard way to persist a login session across browser instances. This article shows how to capture cookies after login, save them to disk, and load them back into a new browser instance, along with the domain, expiry, and security conditions that affect whether the restored session works.
Why Cookie Persistence Matters for Login Sessions
A web application typically issues a session cookie after you submit valid credentials. That cookie is sent with every subsequent request to prove you are authenticated. If you close the browser and start a new Selenium session, the cookie is gone unless you explicitly save it. Re-logging in each time not only adds seconds to your script but may also trigger CAPTCHAs or account lockouts when repeated too often.
By persisting cookies, you can skip the login step entirely on subsequent runs. This is especially useful for long-running scrapers, test suites that need an authenticated state, or any automation that runs on a schedule.
How Selenium Exposes Cookies
Selenium's WebDriver provides two methods for working with cookies:
get_cookies()returns a list of dictionaries, each representing a cookie.add_cookie(cookie_dict)adds a cookie to the current domain.
These methods operate on the driver instance. The cookie dictionary includes fields like name, value, domain, path, expiry, secure, and httpOnly. When you add cookies back later, these fields help recreate the session accurately.
Saving Cookies After a Successful Login
After you perform the login steps, call get_cookies() and serialize the result to disk. A common approach is to store the list as JSON, since it is human-readable and easy to edit if needed.
import json from selenium import webdriver driver = webdriver.Chrome() driver.get("https://example.com/login") # Perform login steps here: fill form, submit, wait for redirect # ... # After login, capture the session cookies cookies = driver.get_cookies() with open("cookies.json", "w") as f: json.dump(cookies, f)
The expiry field is a Unix timestamp in seconds. If a cookie is a session cookie (no expiry), Selenium may omit the field or set it to None. When you load it back, you may need to handle that case.
Restoring Cookies After Visiting the Domain
To restore a session, you must add cookies while the browser is on the cookie's domain; add_cookie() does not work from a blank page or a different domain. A reliable pattern is to visit the domain with a minimal request, add the saved cookies, and then navigate to the protected page.
import json from selenium import webdriver driver = webdriver.Chrome() # Visit the domain to establish a context for adding cookies driver.get("https://example.com") # Load cookies from file with open("cookies.json", "r") as f: cookies = json.load(f) for cookie in cookies: # Remove fields that Selenium might not accept if 'expiry' in cookie and cookie['expiry'] is None: del cookie['expiry'] driver.add_cookie(cookie) # Now navigate to the protected page driver.get("https://example.com/dashboard")
If the login session is still valid, the server will recognize the cookies and grant access without prompting for credentials.
Handling Cookie Expiry, Domain, and Path Restrictions
Cookies are scoped by domain and path. A cookie saved for example.com will not be sent to www.example.com unless the domain attribute allows it. When you save cookies, the domain field reflects the exact host that set it. If your script uses a different subdomain later, the cookie may not apply.
Similarly, the path attribute restricts which paths the cookie is sent to. Most session cookies use /, but some applications set a more specific path. You should preserve the original path value when adding cookies back.
Expiry is another concern. If a cookie has an expiry timestamp in the past, the browser will discard it. When loading cookies, you can filter out expired ones to avoid errors.
import time now = time.time() valid_cookies = [ c for c in cookies if 'expiry' not in c or c['expiry'] is None or c['expiry'] > now ]
Common Pitfalls When Reusing Cookies
One frequent mistake is trying to add cookies before navigating to the cookie's domain. The browser has no origin context, so add_cookie() raises an InvalidCookieDomainException. Always navigate to the domain first.
Another issue is that some sites bind sessions to the user-agent or IP address. If your Selenium browser uses a different user-agent than the one that originally logged in, the server may reject the session. You can set a consistent user-agent via options to avoid this.
A JSON file is portable and easy to inspect. If you use pickle instead, the serialized format is Python-specific, so JSON is usually the better choice. Be aware that when present, the expiry field is an integer Unix timestamp.
Security Considerations for Stored Cookies
Storing session cookies in plain text is risky. Anyone with access to the file can impersonate the authenticated user. If you must persist cookies, restrict file permissions and consider encrypting the file. For example, you could use the cryptography library to encrypt the JSON before writing it to disk.
from cryptography.fernet import Fernet key = Fernet.generate_key() cipher = Fernet(key) encrypted = cipher.encrypt(json.dumps(cookies).encode()) with open("cookies.enc", "wb") as f: f.write(encrypted)
When loading, decrypt and parse the JSON. This adds a small overhead but protects the session token from casual exposure. Also, never commit cookie files to version control; add them to .gitignore.
Handling Session Expiry and Re-authentication
A saved session does not last forever. The server may expire the session after a period of inactivity or force re-authentication for security reasons. Your automation should detect when the session is no longer valid and fall back to the login flow.
A simple heuristic is to check for a known element on the authenticated page, such as a logout button or a user profile link. If that element is absent, assume the session expired and re-login.
from selenium.webdriver.common.by import By from selenium.common.exceptions import NoSuchElementException def is_logged_in(driver): try: driver.find_element(By.CSS_SELECTOR, "#logout-button") return True except NoSuchElementException: return False driver.get("https://example.com/dashboard") if not is_logged_in(driver): # perform login again login(driver) # save new cookies with open("cookies.json", "w") as f: json.dump(driver.get_cookies(), f)
This ensures your script remains robust even when sessions expire mid-run. The re-login step should also update the saved cookie file so the next run starts fresh.