How to Set Cookies with Pyppeteer
Set cookies in Pyppeteer with page.setCookie, handle URL scope and isolation, and fix common blank-page and cookie errors.
Use Pyppeteer’s asynchronous page.setCookie method. Navigate to an HTTP or HTTPS page first, then pass one or more dictionaries containing at least name and value. If you omit url, Pyppeteer derives the cookie scope from the page’s current HTTP URL.
await page.goto('https://example.com')
await page.setCookie({
'name': 'session',
'value': 'abc123',
'url': 'https://example.com',
'httpOnly': True,
'secure': True,
'sameSite': 'Lax',
})
setCookie is a coroutine, so call it with await. The Pyppeteer reference documents name and value as required, with optional url, domain, path, expires, httpOnly, secure and sameSite fields. See the Pyppeteer API reference for the version you installed.
1. Install Pyppeteer and run a complete example
Install the package with pip:
python -m pip install pyppeteer
The first run can download Chromium unless a compatible browser executable is already available. This script navigates before setting the cookie, reloads the page so the cookie is sent with a request, and prints the browser’s visible cookies.
import asyncio
from pyppeteer import launch
async def main():
browser = await launch(headless=True)
page = await browser.newPage()
try:
await page.goto('https://example.com', {
'waitUntil': 'networkidle2',
'timeout': 60_000,
})
await page.setCookie({
'name': 'session',
'value': 'abc123',
'url': 'https://example.com',
'path': '/',
'httpOnly': True,
'secure': True,
'sameSite': 'Lax',
})
# Make a new request so the cookie is included in navigation.
await page.reload({
'waitUntil': 'networkidle2',
'timeout': 60_000,
})
# httpOnly cookies will not appear in document.cookie.
print(await page.cookies())
finally:
await browser.close()
asyncio.run(main())
For a session cookie that should apply to the current page, you can omit url after navigation:
await page.goto('https://example.com/account')
await page.setCookie({
'name': 'session',
'value': 'abc123',
'path': '/',
'httpOnly': True,
'secure': True,
'sameSite': 'Lax',
})
2. Set several cookies in one call
Pass multiple dictionaries to the same coroutine. Give each cookie an explicit URL or domain when the scopes differ.
await page.setCookie(
{
'name': 'session',
'value': 'abc123',
'url': 'https://example.com',
'path': '/',
'httpOnly': True,
'secure': True,
'sameSite': 'Lax',
},
{
'name': 'experiment',
'value': 'checkout-b',
'url': 'https://example.com',
'path': '/checkout',
'secure': True,
'sameSite': 'Strict',
},
)
Use page.cookies() to inspect cookies visible to the page. A cookie marked httpOnly is intended for HTTP requests and is not exposed through page JavaScript such as document.cookie.
3. Cookie fields and how to choose them
| Field | Required | What it controls | Example |
|---|---|---|---|
name |
Yes | Cookie key. | session |
value |
Yes | Stored value. Supply the exact token or preference string expected by the site. | abc123 |
url |
No | URL scope for the cookie. Useful when setting a cookie before navigating to a specific origin. | https://example.com |
domain |
No | Domain scope instead of a URL scope. | example.com |
path |
No | Path under which the cookie is sent. | /account or / |
expires |
No | Expiry as a Unix timestamp in seconds. Omit it for a session cookie. | 1893456000 |
httpOnly |
No | Keeps page JavaScript from reading the cookie while allowing HTTP requests to use it. | True |
secure |
No | Restricts transmission to secure HTTPS connections. | True |
sameSite |
No | Cross-site request behavior. The Pyppeteer reference lists Strict and Lax. |
'Strict' |
Choose Strict when the cookie should not accompany cross-site requests. Choose Lax when normal top-level navigation from another site still needs to work. Match secure and the URL scheme to the environment you are automating.
4. Why setting a cookie on about:blank fails
Pyppeteer’s implementation uses the page’s current URL when url is omitted, but only when that URL begins with http. It rejects cookies on about:blank and data: pages with a PageError. Navigate first or provide a suitable HTTP(S) URL or domain.
# Fails because the page is still about:blank:
# await page.setCookie({'name': 'session', 'value': 'abc123'})
# Works because the target scope is explicit:
await page.goto('https://example.com')
await page.setCookie({
'name': 'session',
'value': 'abc123',
'url': 'https://example.com',
})
Also verify that the URL, domain and path match the page you later load. A cookie scoped to /checkout will not be sent to an unrelated path.
5. Isolate sessions with browser contexts
browser.newPage() uses the browser’s default context. Pyppeteer also supports an incognito BrowserContext, which does not share cookies or cache with other contexts. Create the context first, then create the page from it when tests or jobs need separate login states.
import asyncio
from pyppeteer import launch
async def isolated_session(token):
browser = await launch(headless=True)
context = await browser.createIncognitoBrowserContext()
page = await context.newPage()
try:
await page.goto('https://example.com/login')
await page.setCookie({
'name': 'session',
'value': token,
'url': 'https://example.com',
'httpOnly': True,
'secure': True,
'sameSite': 'Lax',
})
await page.reload({'waitUntil': 'networkidle2'})
return await page.title()
finally:
await browser.close()
print(asyncio.run(isolated_session('abc123')))
6. Troubleshooting common errors
| Symptom | Likely cause | Fix |
|---|---|---|
PageError mentioning about:blank or data: |
No HTTP URL is available for an omitted url. |
Navigate first, or set an explicit HTTPS url or domain. |
Cookie appears in page.cookies() but not in document.cookie |
The cookie is httpOnly. |
This is expected. Check it through a request or page.cookies(); do not remove httpOnly unless page JavaScript must read it. |
Cookie is not sent after setCookie |
The page has not made a new request, or URL/domain/path does not match. | Reload or navigate after setting it and verify scope fields. |
| Secure cookie is missing on local HTTP | secure=True limits transmission to HTTPS. |
Use HTTPS for the test, or use a non-secure test cookie only in a controlled local environment. |
| Authentication still fails | The token is expired, the site needs more cookies, or the cookie’s path/domain is too narrow. | Copy all required cookies, preserve their scopes and expiry, then inspect page.cookies() before reloading. |
| Different jobs affect each other’s login | Pages share the default browser context. | Create an incognito context per session or job. |
| Chromium launch or download error | Pyppeteer has not downloaded Chromium or cannot find the configured executable. | Let the first run complete its download, install a compatible browser separately, or pass the executable path supported by your installed version. |
7. Reliability, performance and security notes
- Set cookies before the request that requires them. A cookie added after navigation only affects subsequent matching requests.
- Use explicit
url,domainandpathvalues in repeatable automation. It makes scope errors easier to diagnose than relying on the current page URL. - Reuse a browser process when running many jobs, but keep unrelated identities in separate incognito contexts. Closing the browser in a
finallyblock prevents leaked processes. - Use realistic expiry values. An expired Unix timestamp will not create a lasting session.
- Keep session tokens out of source code and logs. Pass them through environment variables or a secret store, and avoid printing cookie values in CI output.
- Pyppeteer is an unofficial Python port of Puppeteer. Check the installed package’s reference and source before depending on undocumented fields or behavior; the surfaced documentation is version 0.0.25.
8. cURL and Node.js equivalents outside Pyppeteer
These examples send a cookie with an HTTP request; they do not create a browser cookie jar or execute page JavaScript.
curl 'https://example.com/account' \\
-H 'Cookie: session=abc123'
const response = await fetch('https://example.com/account', {
headers: { Cookie: 'session=abc123' },
});
console.log(await response.text());
Use Pyppeteer when the site depends on browser navigation, JavaScript, rendering or browser storage. Use an HTTP client when sending a cookie header is sufficient.
9. Or skip the browser setup
If your goal is a clean image or PDF of a page after handling consent UI, ScreenshotNeo provides a single screenshot request. Its capture flow removes cookie and consent banners, newsletter popups and chat widgets before the shot; bot checks, blank pages, failed loads, timeouts and cache hits are not billed. Responses identify the result with X-Page-Verdict and X-Billed headers. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for AI agents.
curl -G "https://api.screenshotneo.com/v1/shot" \\
-d access_key=YOUR_API_KEY \\
--data-urlencode url=https://stripe.com \\
-o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo API documentation for request options. The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
10. FAQ
Can I call setCookie before goto?
Only when each cookie has a valid HTTP(S) url or domain that Pyppeteer can use. Calling it on an unconfigured about:blank page fails.
Does setCookie persist after the browser closes?
Session state belongs to the browser profile or context. Treat it as temporary unless your workflow explicitly preserves the profile data.
Why use an incognito context instead of a new page?
A new page in the default context can share cookies and cache. An incognito context gives the workflow an isolated cookie and cache store.
What time unit does expires use?
Pyppeteer’s documented field uses Unix time in seconds.


