Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use one HTMLSession for every request that must share state, then explicitly forward that session’s cookies when Chromium renders the page: response.html.render(send_cookies_session=True). Rendering is a second request in a browser context, so cookie persistence in Requests and cookie forwarding to Chromium are separate steps.
The reliable pattern
A requests-html workflow has two state boundaries:
| Stage | Where state lives | What to do |
|---|---|---|
| HTTP requests | The HTMLSession cookie jar |
Use the same session object for setup, authentication, and the page request. |
| JavaScript rendering | A Chromium page created by render() |
Pass send_cookies_session=True so cookies in the HTML session are sent to the rendering request. |
| Rendered result | response.html.html |
Read the HTML after rendering; it has been replaced with the JavaScript-rendered content. |
The forwarding flag defaults to false. Merely using an HTMLSession does not mean its cookies are automatically supplied to Chromium.
Complete Python example
This example keeps the setup request and the page request on one session, forwards its cookies, and closes the session even when rendering fails.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
from requests_html import HTMLSession
session = HTMLSession()
try:
# Establish any permitted session state through this same object.
setup_response = session.get("https://example.com/login-or-session-establishing-page")
setup_response.raise_for_status()
# If the site requires a login or another setup request, perform that
# authorized workflow through `session` here. Do not hard-code credentials.
response = session.get("https://example.com/page-to-render")
response.raise_for_status()
# Forward cookies held by HTMLSession to the Chromium render request.
response.html.render(send_cookies_session=True)
rendered_html = response.html.html
print(rendered_html)
finally:
session.close()
Replace the example URLs and setup logic with the site’s documented, authorized flow. The important details are the single session instance and the explicit send_cookies_session=True argument.
#1 Best Overall
What happens during rendering
1. Requests stores cookies
Requests sessions persist cookies across requests made through that session. A response’s Set-Cookie headers update the session jar, and later requests made by the same object can send those cookies back. HTMLSession provides this session behavior along with connection pooling.
2. The page is fetched before rendering
session.get() gives you a normal Requests response. At this point, you can check the status code, inspect headers, and confirm that the expected cookies are present in the session jar without printing their values.
3. render() reloads the page in Chromium
The requests-html API describes rendering as reloading the response in Chromium, executing JavaScript, and replacing the response’s HTML with an updated version. It is therefore a distinct browser load, not JavaScript execution inside the original Requests connection.
Recommended Free Tools
4. Cookie forwarding must be enabled
send_cookies_session=True tells requests-html to send cookies from HTMLSession.cookies to that rendering request. The default is False. The API also exposes a separate cookies argument when you need to provide cookie data directly, but never publish live authentication cookies or place them in source control.
5. Read the replaced HTML
After rendering, read response.html.html or query the updated response.html object. Keep a reference to the response if you need both the original HTTP metadata and the rendered document.
Rank #2
Preserving an authenticated workflow
Keep every setup request on the same object
Do not create a new HTMLSession between a login, a consent step, an anti-CSRF bootstrap request, and the page you intend to render. A new object has a different cookie jar. Redirects followed by Requests remain part of the same session, so you normally do not need to copy cookies manually between those HTTP calls.
Follow the site’s authorized login process
Some sites require a form submission, an API token, or a multi-step challenge. Implement that flow according to the site’s terms and documentation, using the same session. Avoid guessing field names or automating a challenge that the site does not permit you to automate. The example deliberately leaves login details out so credentials are not embedded in a tutorial.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Verify state without leaking secrets
For diagnosis, inspect cookie names, domains, and paths rather than values:
for cookie in session.cookies:
print(cookie.name, cookie.domain, cookie.path)
A cookie can exist in the jar but still not be sent if its domain, path, expiration, Secure, or SameSite rules do not match the requested URL. Check that the setup and target URLs are on the expected host and scheme.
Render only after the HTTP state is ready
Fetch the target page after the setup request, then call render(). If you render an earlier response and later perform login, that already-rendered response will not retroactively become authenticated; fetch and render the target again after state changes.
What cookie forwarding does—and does not—guarantee
Forwarding the Requests cookie jar is the documented bridge between the HTTP session and the browser request. It is not a site-independent guarantee that a login will work. A site may bind authentication to state beyond ordinary cookies, such as browser-held storage, a device signal, a token created by JavaScript, or a challenge that must be completed in the browser.
In particular, do not assume that cookies created during Chromium rendering are automatically copied back into HTMLSession.cookies. The documented option concerns sending the session’s cookies into the render request; it does not promise a complete, bidirectional synchronization of every browser state store. If the rendered page establishes new state that a later HTTP request needs, verify the behavior for that site and version rather than relying on an assumption.
Supplying cookies explicitly
When the caller already has cookie data from an authorized source, requests-html’s render API has a separate cookies parameter. Use it instead of putting secrets in a URL or a checked-in file. Keep cookie data in an environment variable or a secret manager, restrict its scope and lifetime, and avoid logging the render call with headers or cookie contents.
Explicit cookies are useful when the state is not stored in the current HTMLSession, but they do not solve state that lives outside cookies. The same domain, path, HTTPS, and expiration rules still matter, and the site may require additional browser context.
First-run setup, versions, and reliability
Chromium download
The first render downloads Chromium through pyppeteer according to the requests-html documentation. Account for that one-time setup in a build or deployment environment: the process needs permission to write the browser cache and enough disk space and network access for the download. A later run can still fail if a deployment image is rebuilt without the cached browser.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Pin and inspect your installed version
The official requests-html material describing these APIs is old, and the exact behavior depends on the installed requests-html, pyppeteer, and Chromium versions. Check the render signature in the version you deploy and test it in the same environment as production. Do not treat an old documentation example as a guarantee for every current combination.
Separate HTTP failures from render failures
Call raise_for_status() before rendering so an authentication redirect or a server error is not mistaken for a JavaScript problem. Then handle exceptions around render() separately. This makes it clear whether the failure occurred while obtaining the page, downloading or launching Chromium, or executing the page.
Control resource use
Rendering launches a browser and is more expensive than a normal Requests fetch. Reuse one session for related requests, render only pages that need JavaScript, and close the session in a finally block. For repeated jobs, isolate browser work so a crashed Chromium process cannot silently invalidate the rest of your HTTP workflow.
Common failures and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The rendered page is logged out | The render call did not forward the session jar, or a new session was created. | Use the same HTMLSession for setup and target requests, and call render(send_cookies_session=True). |
| Cookies appear in the jar but are not used | The cookie domain, path, scheme, or expiration does not match the target. | Inspect names, domains, and paths without printing values; request the matching host and HTTPS URL where required. |
| The first render hangs or fails before page code runs | Chromium has not been downloaded, cannot launch, or lacks filesystem/network permissions. | Allow the pyppeteer browser download, make its cache writable, and test the deployment image directly. |
| The HTTP response is successful but content is missing | The page depends on JavaScript and the unrendered response contains only a shell. | Render the target response, then read response.html.html after the render completes. |
| A login works in a normal browser but not here | The site relies on state beyond cookies or requires an interactive challenge. | Confirm the site permits automation, reproduce its authorized flow, and treat cookie forwarding as necessary but not sufficient. |
| Later requests lose the login | The browser may have created state that was never transferred back to the Requests jar. | Do not assume bidirectional synchronization; verify what the site sets and use the site’s supported API or authentication method for subsequent HTTP calls. |
| Code works locally but not in deployment | Different package, pyppeteer, Chromium, permissions, or environment settings. | Pin dependencies where practical, inspect the installed render signature, and test the same image and user account used in production. |
Choosing between session cookies and explicit cookies
| Approach | Best fit | Trade-off |
|---|---|---|
send_cookies_session=True |
Cookies were obtained by Requests during the same authorized workflow. | Simple and avoids copying values, but still does not transfer non-cookie browser state. |
cookies=... |
Cookie data is supplied by a controlled secret store or another authorized component. | Flexible, but you must protect, scope, and format the cookie data correctly. |
| Browser-specific authentication | The site depends on storage, JavaScript-created tokens, or other browser context. | More involved and site-specific; cookie forwarding alone cannot promise success. |
Or skip the browser setup
If your actual goal is a clean image or PDF rather than extracting authenticated DOM content with requests-html, ScreenshotNeo is the first alternative to try: it removes common consent banners, newsletter popups, and chat widgets before capture, and only clean shots are billed.
ScreenshotNeo accepts custom headers, cookies, and Authorization when a target requires controlled access. Its API also reports whether a response was clean or failed through the X-Page-Verdict and X-Billed headers. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing.
See the ScreenshotNeo API documentation for the complete option set. A one-call public-page capture looks like this:
Best Value
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
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)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
It also provides an MCP server for AI agents such as Claude, Cursor, and other MCP clients, with take_screenshot, get_page_info, and capture_pdf tools. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.
FAQ
Can a cookie prove that the whole login state transferred?
No. A cookie can be necessary while the site still requires browser storage, a JavaScript token, device context, or an interactive challenge. Treat successful transfer as site-specific and verify the resulting page.
Should rendered browser cookies be treated as a replacement for the Requests jar?
No. The documented session flag sends cookies into Chromium; it does not define a complete synchronization contract in the other direction. Keep HTTP and browser state conceptually separate unless your site-specific test establishes otherwise.
Frequently Asked Questions
Can a cookie prove that the whole login state transferred?
No. A cookie can be necessary while the site still requires browser storage, a JavaScript token, device context, or an interactive challenge. Treat successful transfer as site-specific and verify the resulting page.
Should rendered browser cookies be treated as a replacement for the Requests jar?
No. The documented session flag sends cookies into Chromium; it does not define a complete synchronization contract in the other direction. Keep HTTP and browser state conceptually separate unless your site-specific test establishes otherwise.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.

