#!/usr/bin/env -S uv run --script # /// script # dependencies = ["playwright"] # /// """ Headless Firefox with your cookies via cookiefire. Usage: playfox https://twitter.com playfox -P jtm https://private.site playfox --interactive https://site.com """ import subprocess import sys from playwright.sync_api import sync_playwright def parse_netscape_cookies(cookie_text): """Convert cookiefire output to Playwright format.""" cookies = [] for line in cookie_text.strip().split("\n"): if line.startswith("#") or not line.strip(): continue parts = line.split("\t") if len(parts) >= 7: domain, _, path, secure, expires, name, value = parts[:7] exp = float(expires) if exp <= 0: exp = -1 elif exp > 9999999999: exp = exp / 1000 cookies.append( { "name": name, "value": value, "domain": domain, "path": path, "expires": exp, "httpOnly": False, "secure": secure.upper() == "TRUE", "sameSite": "Lax", } ) return cookies def main(): args = sys.argv[1:] profile = "jtm" url = None dump = False interactive = False i = 0 while i < len(args): if args[i] == "-P" and i + 1 < len(args): profile = args[i + 1] i += 2 elif args[i] == "--dump": dump = True i += 1 elif args[i] == "--interactive" or args[i] == "-i": interactive = True i += 1 elif args[i].startswith("http"): url = args[i] i += 1 else: i += 1 if not url: print("Usage: playfox [-P profile] [--dump] [--interactive] URL", file=sys.stderr) sys.exit(1) # get cookies cookie_text = subprocess.check_output(["cookiefire", profile], text=True) cookies = parse_netscape_cookies(cookie_text) with sync_playwright() as p: browser = p.firefox.launch(headless=True) context = browser.new_context() context.add_cookies(cookies) page = context.new_page() # logging page.on("console", lambda msg: print(f"[console] {msg.text}")) page.on("pageerror", lambda err: print(f"[error] {err}")) page.on("request", lambda req: print(f"[req] {req.method} {req.url}")) page.goto(url) if dump: print(page.content()) if interactive: print("\n--- interactive mode ---") print("page object available as 'page'") print("ctrl-d to exit\n") import code code.interact(local={"page": page, "context": context, "browser": browser}) browser.close() if __name__ == "__main__": main()