launch() for a connection to Browser. Your parsing, storage and scheduling stay as they are, and you can retire proxy rotation and header tricks.
Uses: Fetch with Adaptive Stealth Mode (mode=auto), Browser, css_extractor, Extract, Batch
Ask your AI agent
With the Zenrows MCP server connected to Claude Code, Cursor or another coding agent, open your scraper’s code and paste this prompt:Choose your path
Replace the HTTP request with Fetch
Before, the scraper sends the request itself, with hand-made headers:Python (before)
mode=auto renders JavaScript and uses premium proxies only when a page needs them, so you drop headers and proxies. The parsing function doesn’t change:
Python (after)
Drop the parser with a CSS extractor or Extract
When you’re ready, let Zenrows return JSON instead of HTML. Move your selectors into acss_extractor and delete the parsing code:
Python
css_extractor with extract=auto and read the product from the parsed field. See Get structured JSON from any page.
Replace the local browser with Zenrows Browser
Puppeteer and Playwright scrapers keep their page code. Only the line that starts the browser changes: connect towss://browser.zenrows.com instead of launching a local Chromium. Install puppeteer-core or playwright (no bundled browser needed).
finally block, as above, so every session ends when your code is done. If your scraper only loads pages and reads HTML, with no clicks or logins, Fetch is the lighter option: it returns the rendered page in one request.
Scale out with Batch
If your scraper loops over a long URL list with its own queue, retries and concurrency control, hand the list to Batch instead: one job, parallel fetching, automatic tracking of failures, and results you download when the job ends. The samemode, css_extractor and extract parameters go in the job’s zenrows_params. See Scrape a list of URLs.
Migration checklist
- Before: list every place that sends a request or launches a browser, note the custom headers, cookies and proxies each one uses, and test Zenrows on a few real target URLs.
- During: replace the request or
launch()call, keepmode=autoas the default, set client timeouts to 180 seconds, and read the API key from an environment variable. - After: remove proxy rotation and User-Agent lists, drop parsing dependencies you replaced with
css_extractoror Extract, and log theX-Request-CostandX-Request-Idresponse headers.
Example output
The Fetch migration and thecss_extractor version return the same data for the test product:
Customize it
Troubleshooting
- The selectors return nothing after the migration: Zenrows returned the rendered page, which can differ from the raw HTML your old scraper saw. Save
response.textonce, check the element’s selector in it, and update the selector. - Requests fail with
429: you’re sending more requests at once than your plan’s concurrency. Cap your workers at theConcurrency-Limitheader value. - Requests fail with
402: the account is out of credits (AUTH004) or the API key reached one of its credit caps (AUTH014). - Requests end with a client timeout or
499: your HTTP client gave up first. Set its timeout to 180 seconds. page.gotohangs in Puppeteer:networkidle0andnetworkidle2wait for every background request. UsewaitUntil: "domcontentloaded"and wait for the element you need.
Related recipes
Build a price monitor
A complete monitor with price history and drop alerts.
Get structured JSON from any page
Replace selectors with Extract on prepared retailers.
Connect Playwright or Puppeteer to Zenrows Browser
Every connection option for Browser.
Retry failed requests
Add retries with backoff around your Zenrows calls.