Skip to main content
Point Crawl at a homepage, category or search page and it follows the links for you: it opens each page with Fetch in Adaptive Stealth Mode, keeps the URLs that match your patterns, removes duplicates, and stores each page’s HTML. You write no link loop, queue or deduplication. Uses: Crawl (POST /v1/crawls, output_format, include_patterns)

Ask your AI agent

With the Zenrows MCP server connected to Claude, Cursor or any MCP client, paste this prompt. Your agent picks the right Zenrows tools and settings on its own.

Start a crawl and read every page

A crawl is a background job: start it, wait until it ends, then read its results and each page’s HTML.
  1. POST /v1/crawls with the start url, your include_patterns and "output_format": "html". Keep the crawl_id.
  2. Poll GET /v1/crawls/{crawl_id} until status is no longer running.
  3. Read the results, sending each response’s next_cursor as cursor until it is null.
  4. Download each page from its content_url.
Read the results once the crawl has ended: that’s when every kept page has its content_url. Each page Crawl opens is one Fetch request in Adaptive Stealth Mode, and max_pages sets how many it opens.

Example output

A finished crawl reads like this. Each result carries the page’s content_url:

Crawl with the SDKs

ZenRowsCrawlClient wraps the same calls. create starts the crawl, wait polls until it ends, results follows the cursor for you, and content downloads a page’s HTML.
The Node.js SDK takes camelCase arguments (maxPages, includePatterns) and returns fields in the API’s form (crawl_id, content_status). See the Python and Node.js SDK guides.

Crawl from the CLI

--output-format html stores each kept page, and --follow waits until the crawl ends. Then list the URLs, or save everything, HTML included, to one NDJSON file:
CLI
Output (content URLs shortened)
Each line of products.jsonl holds url, content_status and the page’s HTML in content. To read one page, run zenrows crawl content <crawl_id> <content_id>. See the CLI guide.

Customize it

Troubleshooting

  • The crawl returns few URLs: include_patterns also decides which links Crawl opens. Add the paths of the listing or pagination pages that lead to your items, such as /page/ or /category/.
  • content_status reads pending: the crawl is still fetching that page. Wait for the crawl to end, then read the results again from the start.
  • stop_reason is max_items or max_pages: the site holds more. Start a new crawl with higher values.
  • 429 with too_many_crawls: your account’s Crawl and Batch jobs are all running. Wait the Retry-After seconds, then start the crawl.
  • status: failed with seed_unreachable: the start URL didn’t load. Open it in a browser to check it, then start again.

Map every URL on a website

Build a URL inventory and export it as CSV.

Scrape a list of URLs

Feed the URLs you found into one Batch job.

Build a RAG knowledge base from a website

Crawl a site and turn every page into markdown chunks.

Extract data with CSS selectors

Parse each crawled page with BeautifulSoup or Cheerio.