# Instant Data Scraper: Extract Any List or Table to CSV (`zaiq/instant-data-scraper`) Actor

Instant data scraper for any website, no code: paste a URL and it finds the main list or table (products, search results, listings, directories), extracts every item into clean columns, follows next pages, Load more and infinite scroll, and exports CSV, Excel or JSON.

- **URL**: https://apify.com/zaiq/instant-data-scraper.md
- **Developed by:** [Zaiq](https://apify.com/zaiq) (community)
- **Categories:** Developer tools, Automation, E-commerce
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Instant Data Scraper: Extract Any List or Table to CSV

Paste the address of any web page that shows a list or a table: search results, a product grid, a directory, job or
property listings, a ranking, forum threads or an HTML table. The scraper finds the page's main list automatically,
extracts every item into clean columns, follows the next pages, and gives you rows ready for **CSV, Excel or JSON**.
No code, no CSS selectors, no browser extension to babysit: it runs in the cloud and works through the API too.

### What it does

- **Finds the list for you.** It looks for the repeated items on the page (cards, rows, results, posts) and ranks them,
  so the main content wins over menus, footers, sidebars, filters and footnotes. HTML tables are read with their
  header row as column names.
- **Clean columns.** Text, links and image addresses become separate columns with readable names (`title`,
  `titleUrl`, `price`, `rating`, `author`, `comments` ...) taken from the page's own markup. Prices also get
  `priceAmount` and `priceCurrency` columns, star ratings become numbers, truncated titles are replaced by the full
  title, and tags or other repeated values are joined into one column. Labels such as "Price:", buttons such as "Add
  to basket" and empty columns are left out.
- **Follows pagination.** Next links and arrows in many languages, page numbers (1 2 3 ...), "Load more" buttons and,
  when you switch it on, infinite scrolling. Every page keeps the same columns.
- **Handles JavaScript pages.** If a list only appears after JavaScript runs, or a site turns plain requests away, the
  page is loaded in a real browser (Chrome).
- **Free preview.** Preview mode lists every list and table found on a page, with item counts, columns and sample
  rows, so you can pick another one with **Which list**.
- **Optional AI column names.** One short AI call per list renames the columns (for example `ageUrl` becomes
  `discussionUrl`, `avatars` becomes `contributorImages`).
- **Any country (optional).** Fetch pages through home (residential) connections in a country you choose, confirmed
  by two IP-location services, to get local prices, language and listings.
- **No duplicates.** An item seen before in the run (on two pages, or a repeated "featured" item) is written and
  charged once.

### Who uses it

- **E-commerce and pricing teams:** product grids and search results with names, prices, ratings, images and links.
- **Lead generation and research:** directories, member lists, company and organisation listings, job boards.
- **Real estate:** property listings with price, bedrooms, bathrooms, size, location and link.
- **Analysts and journalists:** Wikipedia and statistics tables, rankings, rates and leaderboards into a spreadsheet.
- **Anyone who used a browser extension** to grab a list into CSV and now wants it scheduled, repeatable, or as an API.

### Example

Input:

```json
{
  "startUrls": [{ "url": "https://books.toscrape.com/" }],
  "maxPages": 2
}
```

One of the 40 rows (20 books per page, two pages):

```json
{
  "thumbnail": "https://books.toscrape.com/media/cache/2c/da/2cdad67c44b002e7ead0cc35693c0e8b.jpg",
  "rating": 3.0,
  "title": "A Light in the Attic",
  "titleUrl": "https://books.toscrape.com/catalogue/a-light-in-the-attic_1000/index.html",
  "price": "£51.77",
  "priceAmount": 51.77,
  "priceCurrency": "GBP",
  "_sourceUrl": "https://books.toscrape.com/",
  "_page": 1,
  "_position": 1,
  "_listIndex": 1
}
```

The same input with `https://news.ycombinator.com/` gives one row per story, from a page built with tables and two
rows per story:

```json
{
  "rank": "1.",
  "title": "Run Qwen 3.8 Flash Next (125B) on consumer hardware (RTX 4090) at 100T/s",
  "titleUrl": "https://github.com/Niko1221/Strata",
  "siteUrl": "https://news.ycombinator.com/from?site=github.com/niko1221",
  "site": "github.com/niko1221",
  "score": "220 points",
  "user": "snehesht",
  "userUrl": "https://news.ycombinator.com/user?id=snehesht",
  "datetime": "2026-10-04T12:51:53",
  "age": "3 hours ago",
  "ageUrl": "https://news.ycombinator.com/item?id=49953495",
  "comments": "102 comments",
  "_sourceUrl": "https://news.ycombinator.com/",
  "_page": 1,
  "_position": 1,
  "_listIndex": 1
}
```

A Wikipedia list page gives its main table, with the table's own headers as columns (`Location`, `Location URL`,
`Population`, `% of world`, `Date`, `Source`), 240 rows.

#### Tested on 40 public pages (4 October 2026)

Product grids, search results, directories, job boards, property listings, forums, rankings, Wikipedia and statistics
tables, JavaScript-only pages, a "Load more" page and an infinite list, read through residential connections with up
to two pages each:

| | |
|---|---|
| Pages with rows | 38 of 40 (the other two blocked automated visits even in a browser; nothing charged) |
| Right list chosen first | 38 of 38 |
| Rows | 3,755 from 58 pages, in about 2 minutes |
| Pages that needed a browser | 8 (a JavaScript list, a "Load more" button, and sites that turn plain requests away) |

Also tested: "Load more" (24 laptops: the first 6 plus 3 clicks), infinite scrolling (all 100 quotes of a scrolling
list: the first 10 plus 3 scrolls), preview mode, a second table chosen with Which list, your own item selector and fields, a spending limit
(the run stopped at exactly the limit), and a run moved to another server mid-way (it continued at the next page and
charged no row twice).

### Input

| Field | What it does |
|---|---|
| `startUrls` | The pages with the lists or tables you want. One row per item. |
| `maxPages` | Pages to read per URL: the first page plus next pages, "Load more" clicks or scrolls. Default 5. |
| `maxItems` | Stop after this many rows in total. Default 1,000. |
| `previewOnly` | Return the lists found on each page (up to 10 URLs) with sample rows instead of extracting. Free. |
| `listIndex` | 1 = the best match. Use 2, 3 ... for another list or table on the page (see preview or `LISTS`). |
| `renderMode` | `auto` (default): plain HTML first, a real browser only when needed. `never` or `always`. |
| `clickLoadMore` | Click "Load more" / "Show more" buttons. Default on. |
| `infiniteScroll` | Scroll lists that load more items as you scroll. Default off. |
| `waitForSelector` | In the browser, wait for this element before reading the page. |
| `includeTables` | Treat HTML tables as lists, with their headers as column names. Default on. |
| `dedupeItems` | Write identical rows once. Default on. |
| `itemSelector` | Optional CSS selector of one item, for example `article.product_pod`. Columns are still found for you. |
| `fields` | Optional own columns: `{"title": "h3 a@title", "price": ".price_color", "url": "h3 a@href"}`. `@href` and `@src` give full addresses, `@html` the HTML, any other `@attribute` its value; no `@` gives the text. |
| `aiColumnNames` | Clearer column names from an AI model, one call per list. Default off. |
| `country` | Optional two-letter code. Pages are fetched through residential connections in that country, verified. |
| `proxyConfiguration` | Used when no country is set. Default: Apify residential proxy. |
| `maxConcurrency` | URLs read at the same time. Default 5. |

### Output

- **Dataset:** one row per item, with the detected columns plus `_sourceUrl` (the page it came from), `_page` (1 for
  the first page; each next page, "Load more" click or scroll adds one), `_position` (its place in the list) and
  `_listIndex`. Export as CSV, Excel (XLSX), JSON, JSONL, XML or HTML from the Storage tab or through the API
  (`.../items?format=csv`).
- **`LISTS`** (key-value store): for each URL, every list and table found on its first page, numbered, with item count,
  description, item selector, columns and three sample rows.
- **`SUMMARY`** (key-value store): per URL, pages read, rows, the list used, why it stopped (page limit, no next page,
  no new items, spending limit) and any failures; plus traffic and charges for the run.

Columns follow the page's structure, so different sites give different columns. For one clean spreadsheet, run one
site (or one kind of page) per run.

### Use it from code, automations and AI agents

- **API**: run it and get the results in one call: `POST https://api.apify.com/v2/acts/zaiq~instant-data-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN` with the input as JSON. The API tab on this page has ready-made Python, JavaScript and cURL examples.
- **Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("zaiq/instant-data-scraper").call(run_input={'startUrls': [{'url': 'https://books.toscrape.com/'}], 'maxPages': 2})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

- **No code**: connect it to Google Sheets, Zapier, Make or n8n from the Integrations tab, schedule runs in Apify Console, and get a webhook when a run finishes.
- **AI agents (MCP)**: add it as a tool to Claude, Cursor or any MCP client through Apify's MCP server: `https://mcp.apify.com?tools=zaiq/instant-data-scraper`.

### Pricing

You pay only for rows delivered.

| Event | Price |
|---|---|
| Row extracted (one item of the list or table) | $0.003 ($3 per 1,000 rows) |
| Page loaded in a real browser that gave new rows | $0.05 |

Plus Apify's standard run start fee.

Free: preview mode, duplicate rows, pages that fail, are blocked, have no list or bring no new rows, and every retry.
"Load more" clicks and scrolls inside a browser page are part of that page. A browser is used only when a page needs
it (or when you choose Always). AI column names, when switched on, are billed through Apify's OpenRouter integration to
the account that runs the Actor, about $0.0003 per list in our tests.

Your spending limit for the run is respected: the run stops cleanly at the limit.

### Tips

- **Wrong list?** Run once with **Preview** on (free), look at the lists found, and set **Which list** to the one you
  want. The `LISTS` record of every normal run shows the same.
- **A list behind "Load more"?** Leave **Click 'Load more' buttons** on and raise **Pages to follow**.
- **An infinite list?** Switch on **Scroll infinite lists**; each scroll counts as a page.
- **Exact columns?** Give **Fields** with CSS selectors; only those columns are returned.
- **Local prices or language?** Set **Country**.

### Limits

- One list per URL in a run (choose which with **Which list**). For a second list from the same page, run again with
  its number.
- Pages behind a login, forms that must be filled in, and lists inside iframes or shadow DOM are not covered.
- Some sites block automated visits even through home connections and a real browser. Those pages come back as
  failures in `SUMMARY` and cost nothing. CAPTCHAs are never solved.
- Columns are named automatically; on unusual layouts names can be generic (`text`, `link`). Use AI column names or
  Fields for exact names. Items whose details vary in position (some listings show more facts than others) can spread
  over more columns.
- Up to 1,000 pages per URL and 1,000,000 rows per run.
- Extract only data you are allowed to access, and follow the site's terms.

### FAQ

**How does it know which list I want?** It scores every group of repeated items on the page by how many items there
are, how much text and how many fields they carry, whether they have links, images and prices, and how much of the
page they cover, and it marks down navigation, headers, footers, sidebars, filters, menus and footnotes. The best
group is list 1.

**Is this the Instant Data Scraper browser extension?** No. It does the same kind of job (find the table or list on a
page and export it) as a cloud tool: no browser to keep open, runs on a schedule, handles many URLs, works through the
API and through residential connections.

**Does it work on JavaScript sites?** Yes. In automatic mode a page whose list is missing from the HTML, or that turns
plain requests away, is loaded in Chrome.

**Can I schedule it?** Yes, like any Apify Actor: save the input as a task and add a schedule; each run writes a new
dataset, and duplicates within a run are skipped.

**What if the run is interrupted?** Progress is saved. A run moved to another server continues at the next page, and
rows already written are never written or charged again.

# Actor input Schema

## `startUrls` (type: `array`):

The pages that show the list or table you want: a category or search results page, a directory, a ranking, a page with a table. One row is returned per item. Add several pages to extract several lists in one run.

## `maxPages` (type: `integer`):

How many pages of each list to read: the first page plus next pages (Next links, page numbers, 'Load more' clicks, or scrolls of an infinite list). 1 reads only the page you gave.

## `maxItems` (type: `integer`):

The run stops after this many rows in total (all URLs together). Only rows are charged, so this also caps the cost.

## `previewOnly` (type: `boolean`):

Read only the first page of each URL (up to 10) and return one row per list or table found on it, best first, with its item count, columns and three sample rows. Nothing is charged. Use it to pick 'Which list' when the best guess is not the one you want.

## `listIndex` (type: `integer`):

1 takes the best match (usually the page's main list). If a page has several lists or tables, set 2, 3 ... to take another one; the run's LISTS record and preview mode show them all, numbered.

## `renderMode` (type: `string`):

Automatic reads each page's HTML first and loads it in a real browser only when the list is missing (built by JavaScript) or a 'Load more' button needs clicking. A page loaded in a browser costs a small extra fee, only when it gives new rows.

## `clickLoadMore` (type: `boolean`):

When a list has a 'Load more' / 'Show more' button instead of next pages, click it (in a browser) up to the page limit. Each click counts as a page.

## `infiniteScroll` (type: `boolean`):

For lists that load more items as you scroll down: scroll in a browser up to the page limit (each scroll counts as a page) and stop when no new items appear.

## `waitForSelector` (type: `string`):

Optional CSS selector. In the browser, wait until it appears before reading the page, for example .product-card for a slow list.

## `includeTables` (type: `boolean`):

Treat <table> elements as lists, with columns named from the table's header row. Switch off to consider only lists and grids of cards.

## `dedupeItems` (type: `boolean`):

A row identical to one already extracted in this run (the same item on two pages, a repeated 'featured' item) is not written again and not charged.

## `itemSelector` (type: `string`):

For power users: the CSS selector of one item, for example article.product_pod or li.result. Its matches become the rows and the columns are still found automatically. Leave empty for automatic detection.

## `fields` (type: `object`):

For power users: your own columns as {"column name": "selector@attribute"}, read inside each item, for example {"title": "h3 a@title", "price": ".price_color", "url": "h3 a@href", "image": "img@src"}. Without @ the element's text is taken; @href and @src give full addresses; @html gives the HTML. When set, only these columns are returned.

## `aiColumnNames` (type: `boolean`):

Ask an AI model for clearer column names (one short call per list, well under $0.001, billed through Apify's OpenRouter integration to the account that runs the Actor). Off: names come from the page's own markup.

## `country` (type: `string`):

Fetch every page through home (residential) connections in this country, confirmed by two IP-location services, to get that country's prices, language and listings. Leave empty for no particular country.

## `proxyConfiguration` (type: `object`):

Used when no country is set. Residential proxies (the default) get through to most sites; the datacenter (automatic) group is enough for many simple sites. With a country set, residential connections in that country are always used.

## `maxConcurrency` (type: `integer`):

How many of your URLs are read at the same time. The pages of one URL are always read in order.

## `maxTriesPerPage` (type: `integer`):

A page that is blocked or fails to load is tried again through a new connection, up to this many times. Failed tries are free.

## `acceptLanguage` (type: `string`):

Optional, for example de-DE. Leave empty to send the country's usual browser language (English when no country is set).

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://books.toscrape.com/"
    }
  ],
  "maxPages": 2,
  "maxItems": 1000,
  "previewOnly": false,
  "listIndex": 1,
  "renderMode": "auto",
  "clickLoadMore": true,
  "infiniteScroll": false,
  "includeTables": true,
  "dedupeItems": true,
  "aiColumnNames": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  },
  "maxConcurrency": 5,
  "maxTriesPerPage": 3
}
```

# Actor output Schema

## `rows` (type: `string`):

Dataset with one row per extracted item. Export it as CSV, Excel, JSON or XML from the Storage tab or the API.

## `csv` (type: `string`):

The same rows as a CSV file (opens in Excel or Google Sheets).

## `lists` (type: `string`):

Every list and table detected on the first page of each URL, numbered, with item counts, columns and sample rows (use the number as 'Which list').

## `summary` (type: `string`):

Per URL: pages read, rows, the list used, why it stopped, failures; plus traffic and charges.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://books.toscrape.com/"
        }
    ],
    "maxPages": 2,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaiq/instant-data-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [{ "url": "https://books.toscrape.com/" }],
    "maxPages": 2,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("zaiq/instant-data-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://books.toscrape.com/"
    }
  ],
  "maxPages": 2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call zaiq/instant-data-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zaiq/instant-data-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/nFChCJWXRcGYdRjk8/builds/e2gUQ0uN2LVnn6BQg/openapi.json
