Python’s http.cookiejar module manages HTTP cookies automatically in urllib sessions, persisting cookies across requests the way a browser would. import http.cookiejar. In-memory jar: jar = http.cookiejar.CookieJar(). File-backed: jar = http.cookiejar.MozillaCookieJar(filename) — Netscape cookies.txt format; jar.load(ignore_discard=True) / jar.save(ignore_discard=True, ignore_expires=True). LWP format: http.cookiejar.LWPCookieJar(filename) — Set-Cookie3 format. Integrate with urllib: opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(jar)) then opener.open(url) — cookies are sent and received automatically. Policy: jar = CookieJar(policy=http.cookiejar.DefaultCookiePolicy(blocked_domains=["ads.example.com"])). Inspect: for cookie in jar: print(cookie.name, cookie.value, cookie.domain, cookie.path, cookie.expires, cookie.secure). Clear: jar.clear() / jar.clear_expired_cookies() / jar.clear(domain, path, name). Cookie attributes: .name, .value, .domain, .path, .expires, .secure, .has_nonstandard_attr(key). Claude Code generates authenticated web scrapers, session-persistent crawlers, cookie-based login flows, and browser cookie importers.
CLAUDE.md for http.cookiejar
## http.cookiejar Stack
- Stdlib: import http.cookiejar, urllib.request
- Memory: jar = http.cookiejar.CookieJar()
- File: jar = http.cookiejar.MozillaCookieJar("cookies.txt")
- jar.load(ignore_discard=True) # load saved cookies
- jar.save(ignore_discard=True) # persist after session
- Opener: opener = urllib.request.build_opener(
- urllib.request.HTTPCookieProcessor(jar))
- resp = opener.open("https://example.com/login")
- Inspect: for c in jar: print(c.name, c.value, c.domain)
http.cookiejar Cookie Management Pipeline
# app/cookiejarutil.py — session, login, persist, inspect, import
from __future__ import annotations
import http.cookiejar
import json
import ssl
import time
import urllib.error
import urllib.parse
import urllib.request
from dataclasses import dataclass
from pathlib import Path
# ─────────────────────────────────────────────────────────────────────────────
# 1. Session with automatic cookie handling
# ─────────────────────────────────────────────────────────────────────────────
@dataclass
class CookieSession:
"""
HTTP session that automatically manages cookies across requests.
Wraps urllib.request.OpenerDirector with HTTPCookieProcessor.
Example:
session = CookieSession()
resp = session.get("https://httpbin.org/cookies/set?key=val")
print(session.cookies_for("httpbin.org"))
"""
jar: http.cookiejar.CookieJar
opener: urllib.request.OpenerDirector
timeout: int = 30
@classmethod
def create(
cls,
cookie_file: str | Path | None = None,
timeout: int = 30,
verify_ssl: bool = True,
) -> "CookieSession":
"""
Create a new CookieSession with an in-memory or file-backed jar.
Example:
session = CookieSession.create()
session = CookieSession.create(cookie_file="cookies.txt")
"""
if cookie_file is not None:
jar = http.cookiejar.MozillaCookieJar(str(cookie_file))
if Path(str(cookie_file)).exists():
jar.load(ignore_discard=True, ignore_expires=True)
else:
jar = http.cookiejar.CookieJar()
handlers = [urllib.request.HTTPCookieProcessor(jar)]
if not verify_ssl:
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
handlers.append(urllib.request.HTTPSHandler(context=ctx))
opener = urllib.request.build_opener(*handlers)
opener.addheaders = [("User-Agent", "Python/http.cookiejar")]
return cls(jar=jar, opener=opener, timeout=timeout)
def _request(
self,
method: str,
url: str,
data: bytes | None = None,
headers: dict | None = None,
) -> "urllib.response.addinfourl":
req = urllib.request.Request(url, data=data, method=method)
for k, v in (headers or {}).items():
req.add_header(k, v)
return self.opener.open(req, timeout=self.timeout)
def get(
self,
url: str,
headers: dict | None = None,
) -> bytes:
"""
HTTP GET returning response body bytes.
Example:
body = session.get("https://httpbin.org/get")
"""
with self._request("GET", url, headers=headers) as resp:
return resp.read()
def post(
self,
url: str,
data: dict | bytes | None = None,
json_data: object = None,
headers: dict | None = None,
) -> bytes:
"""
HTTP POST with form data, raw bytes, or JSON body.
Example:
body = session.post("https://example.com/login",
data={"user": "alice", "pw": "s3cr3t"})
"""
hdrs = dict(headers or {})
if json_data is not None:
body = json.dumps(json_data).encode("utf-8")
hdrs.setdefault("Content-Type", "application/json")
elif isinstance(data, dict):
body = urllib.parse.urlencode(data).encode("utf-8")
hdrs.setdefault("Content-Type", "application/x-www-form-urlencoded")
else:
body = data or b""
with self._request("POST", url, data=body, headers=hdrs) as resp:
return resp.read()
def cookies_for(self, domain: str) -> list[dict]:
"""
Return all cookies for a domain as a list of dicts.
Example:
cookies = session.cookies_for("example.com")
"""
result = []
for c in self.jar:
if domain.lower() in c.domain.lower():
result.append({
"name": c.name,
"value": c.value,
"domain": c.domain,
"path": c.path,
"expires": c.expires,
"secure": c.secure,
})
return result
def save(self, path: str | Path | None = None) -> Path:
"""
Save cookies to disk (Mozilla format).
If jar was created with a file, saves there unless path is given.
Example:
session.save("session.txt")
"""
dest = Path(str(path)) if path else Path(getattr(self.jar, "filename", "cookies.txt"))
jar = http.cookiejar.MozillaCookieJar(str(dest))
for cookie in self.jar:
jar.set_cookie(cookie)
jar.save(ignore_discard=True, ignore_expires=True)
return dest
# ─────────────────────────────────────────────────────────────────────────────
# 2. Cookie inspection helpers
# ─────────────────────────────────────────────────────────────────────────────
@dataclass
class CookieInfo:
name: str
value: str
domain: str
path: str
expires: int | None # Unix timestamp or None (session cookie)
secure: bool
@property
def is_session(self) -> bool:
return self.expires is None
@property
def expires_str(self) -> str:
if self.expires is None:
return "(session)"
import datetime
dt = datetime.datetime.utcfromtimestamp(self.expires)
return dt.strftime("%Y-%m-%d %H:%M UTC")
def __str__(self) -> str:
flags = []
if self.secure:
flags.append("Secure")
if self.is_session:
flags.append("session")
else:
flags.append(f"expires={self.expires_str}")
return (f"{self.domain}{self.path} "
f"{self.name}={self.value[:30]!r} "
f"[{', '.join(flags)}]")
def inspect_jar(jar: http.cookiejar.CookieJar) -> list[CookieInfo]:
"""
Return a list of CookieInfo objects for all cookies in the jar.
Example:
for c in inspect_jar(session.jar):
print(c)
"""
return [
CookieInfo(
name=c.name,
value=c.value,
domain=c.domain,
path=c.path,
expires=c.expires,
secure=c.secure,
)
for c in jar
]
def expired_cookies(jar: http.cookiejar.CookieJar) -> list[CookieInfo]:
"""
Return cookies that have already expired.
Example:
old = expired_cookies(jar)
print(f"{len(old)} expired cookies")
"""
now = time.time()
return [c for c in inspect_jar(jar)
if c.expires is not None and c.expires < now]
# ─────────────────────────────────────────────────────────────────────────────
# 3. Custom cookie policy
# ─────────────────────────────────────────────────────────────────────────────
class StrictSameSitePolicy(http.cookiejar.DefaultCookiePolicy):
"""
Reject cookies from third-party domains (strict same-site behaviour).
Example:
jar = http.cookiejar.CookieJar(policy=StrictSameSitePolicy())
session = CookieSession(jar=jar, opener=...)
"""
def set_ok(self, cookie, request):
req_host = urllib.parse.urlparse(request.get_full_url()).hostname or ""
cookie_domain = cookie.domain.lstrip(".")
if not req_host.endswith(cookie_domain) and req_host != cookie_domain:
return False
return super().set_ok(cookie, request)
# ─────────────────────────────────────────────────────────────────────────────
# 4. Mozilla cookies.txt import/export
# ─────────────────────────────────────────────────────────────────────────────
def load_mozilla_cookies(path: str | Path) -> http.cookiejar.MozillaCookieJar:
"""
Load a Netscape/Mozilla cookies.txt file into a MozillaCookieJar.
Example:
jar = load_mozilla_cookies("/path/to/cookies.txt")
for c in jar: print(c.name, c.domain)
"""
jar = http.cookiejar.MozillaCookieJar(str(path))
jar.load(ignore_discard=True, ignore_expires=True)
return jar
def export_cookies_as_dict(jar: http.cookiejar.CookieJar) -> list[dict]:
"""
Export all cookies as a JSON-serializable list of dicts.
Example:
data = export_cookies_as_dict(jar)
json.dump(data, open("cookies.json", "w"))
"""
return [
{
"name": c.name, "value": c.value,
"domain": c.domain, "path": c.path,
"expires": c.expires, "secure": c.secure,
}
for c in jar
]
# ─────────────────────────────────────────────────────────────────────────────
# Demo
# ─────────────────────────────────────────────────────────────────────────────
if __name__ == "__main__":
import tempfile
print("=== http.cookiejar demo ===")
# ── Simulate a jar with manually added cookies ────────────────────────────
print("\n--- Build jar and inspect ---")
jar = http.cookiejar.CookieJar()
# Manually create a cookie using the internal API for demo purposes
import http.cookiejar as _cj
def _add_cookie(jar, name, value, domain, path="/", expires=None, secure=False):
c = _cj.Cookie(
version=0, name=name, value=value,
port=None, port_specified=False,
domain=domain, domain_specified=True, domain_initial_dot=domain.startswith("."),
path=path, path_specified=True,
secure=secure,
expires=expires,
discard=expires is None,
comment=None, comment_url=None,
rest={},
)
jar.set_cookie(c)
_add_cookie(jar, "session", "abc123", ".example.com", secure=True)
_add_cookie(jar, "pref", "dark", ".example.com")
_add_cookie(jar, "tracker", "xyz", ".ads.example.com",
expires=int(time.time()) - 1000) # already expired
print(" All cookies:")
for c in inspect_jar(jar):
print(f" {c}")
print("\n Expired cookies:")
for c in expired_cookies(jar):
print(f" {c}")
# ── Save and reload ────────────────────────────────────────────────────────
print("\n--- Save / reload MozillaCookieJar ---")
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "cookies.txt"
mjr = http.cookiejar.MozillaCookieJar(str(path))
for cookie in jar:
mjr.set_cookie(cookie)
mjr.save(ignore_discard=True, ignore_expires=True)
print(f" saved to {path.name} ({path.stat().st_size}B)")
loaded = load_mozilla_cookies(path)
print(f" loaded {sum(1 for _ in loaded)} cookies")
# ── export_cookies_as_dict ─────────────────────────────────────────────────
print("\n--- export_cookies_as_dict ---")
data = export_cookies_as_dict(jar)
for d in data:
print(f" {d['name']}={d['value']!r} domain={d['domain']}")
# ── CookieSession live demo (uses httpbin.org) ─────────────────────────────
print("\n--- CookieSession (httpbin.org) ---")
print(" (live requests skipped in demo; pattern shown below)")
print(" session = CookieSession.create()")
print(" session.get('https://httpbin.org/cookies/set/color/blue')")
print(" cookies = session.cookies_for('httpbin.org')")
print("\n=== done ===")
For the requests (PyPI) alternative — requests.Session() with automatic cookie persistence, requests.Session.cookies (a RequestsCookieJar), and session.get(url) / session.post(url, data=...) provide a higher-level interface with connection pooling, SSL verification, automatic encoding detection, and streaming — use requests.Session for any production HTTP client work; use http.cookiejar with urllib.request for zero-dependency scripts, when the full requests library is unavailable, or when writing tests that need to exercise urllib-based code. For the playwright / selenium (PyPI) alternatives — headless browser automation that manages cookies, JavaScript-rendered pages, and complex authentication flows automatically — use browser automation when the site requires JavaScript rendering, device fingerprinting, or CAPTCHA bypass; use http.cookiejar for server-rendered sites where static HTML responses and standard cookie headers are sufficient. The Claude Skills 360 bundle includes http.cookiejar skill sets covering CookieSession with create()/get()/post()/cookies_for()/save(), CookieInfo with inspect_jar()/expired_cookies(), StrictSameSitePolicy custom policy, and load_mozilla_cookies()/export_cookies_as_dict() persistence helpers. Start with the free tier to try cookie session patterns and http.cookiejar pipeline code generation.