Skip to main content
In Lesson 3 you collected product URLs into product_urls.txt. Now you scrape all of them. Rather than looping over the URLs and managing retries and concurrency yourself, you submit them as one Batch job and collect the results when it finishes. What you’ll build: scrape_all.py, a script that scrapes every URL in product_urls.txt in one Batch job and writes the tracker’s first dataset to products.json and products.csv. What you’ll learn:
  • How a Batch job runs many Fetch requests for you, with retries and concurrency handled on Zenrows’ side.
  • How zenrows_params applies the same Fetch parameters to every URL in the job.
  • How to wait for a run, check its stats and download its results with ZenRowsBatchClient.
Time: about 10 minutes.

How a Batch job works

Batch takes a list of tasks (one URL each) and runs them on Zenrows’ infrastructure. You submit the job and get back an ID at once. Zenrows works through the URLs at your plan’s concurrency, retries the ones that fail, and stores each result. Each task costs the same as the Fetch request it runs, and failed tasks are not charged. Every job has a run: the execution of its tasks. You wait for the run to finish, then read its stats and download its results.

Write the scraping script

The script reuses PRODUCT_SELECTORS from Lesson 2, so every product page comes back as the same JSON fields. Create scrape_all.py:
Python (SDK)
Here is what happens in it:
1

Submit the job

client.submit_regular() creates a one-time job from the URL list. Each task gets an external_id, here the product slug, so you can match every result to its product. zenrows_params applies mode=auto and your CSS selectors to every task.
2

Wait for the run

job.run.wait() polls the run until it finishes and returns it. run.stats counts the tasks: total, successful and failed.
3

Download the results

run.download_to_memory() fetches each successful task’s body. With css_extractor, each body is the JSON object you saw in Lesson 2.
4

Write the dataset

as_list() turns a single match into a one-item list, so sizes and colors read the same for every product. The rows go to products.json and products.csv.

Run it

The 42 URLs from Lesson 3 finish in about a minute:
The first rows of products.csv:
Products without options, such as accessories, come back with empty sizes and colors:
That’s the tracker’s first full dataset. Run discover.py with a larger max_pages and then scrape_all.py, and the same two scripts cover the whole store.

Make it your own

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.
Paste three URLs or three thousand: the agent sends them as one job either way.

What you built

scrape_all.py turns the URL list from Lesson 3 into products.json and products.csv. You can:
  • Submit many URLs as one Batch job with ZenRowsBatchClient.submit_regular().
  • Apply Fetch parameters to every task with zenrows_params, and tag tasks with external_id.
  • Wait for a run, read its stats and download its results.

Next lesson

Lesson 5: Add a product to the cart with Browser

Drive a real browser with Playwright: pick a size and color, add to cart, and read the total.