# HTML Table Extractor (`benthepythondev/html-table-extractor`) Actor

Extract structured rows from HTML tables on any web page.

- **URL**: https://apify.com/benthepythondev/html-table-extractor.md
- **Developed by:** [ben](https://apify.com/benthepythondev) (community)
- **Categories:** SEO tools, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## HTML Table Extractor - Scrape Tables to Structured Rows

Extract HTML tables from public web pages and turn them into clean structured rows. The actor reads each target page, finds every `<table>`, detects header cells, normalizes the body rows, and returns one dataset item per table with the headers, row count, column count, and row objects ready for export. Export to JSON/CSV/Excel, run on a schedule, call via API, or connect to Make, Zapier or n8n.

### What is the HTML Table Extractor?

The HTML Table Extractor is a focused utility for pages where useful data is already published in table form but is awkward to copy or automate. Common examples include public directories, statistics pages, comparison pages, government pages, pricing pages, documentation pages, sports tables, release matrices, event schedules, and static reports. Instead of saving the page manually and cleaning the table in a spreadsheet, paste the URLs and let the actor return machine-readable rows.

The actor uses direct HTTP requests and a lightweight parser, not a browser. That keeps runs fast, inexpensive, and reliable for daily scheduled checks. It is best for server-rendered HTML tables. If a website builds its table only after heavy client-side JavaScript, use a browser-based scraper first or paste a URL where the table exists in the returned HTML.

Because the output is already normalized into row objects, it is useful even when the original page contains several unrelated tables. You can filter by `table_index`, keep the table with the expected headers, or join the result with a URL inventory from another actor. For repeatable work, run it with a saved task and export only the columns your workflow needs.

#### What data does it extract?

- Source input URL and final redirected URL
- Domain name
- Table index on the page
- Number of extracted rows
- Number of detected columns
- Header names from `<th>` cells when available
- Generated column names when no header row exists
- Rows as clean key-value objects
- Nested table text collapsed into readable cell text

### Input

| Field | Type | Description |
| --- | --- | --- |
| `urls` | array | Web pages to scan for HTML tables. |
| `maxTables` | integer | Maximum number of tables to return from each URL. |

#### Example input

```json
{
  "urls": [
    "https://www.w3schools.com/html/html_tables.asp",
    "https://example.com/report.html"
  ],
  "maxTables": 10
}
````

### Output

Each dataset item represents one table. The `rows` field contains the normalized records.

```json
{
  "input": "https://www.w3schools.com/html/html_tables.asp",
  "url": "https://www.w3schools.com/html/html_tables.asp",
  "final_url": "https://www.w3schools.com/html/html_tables.asp",
  "domain": "www.w3schools.com",
  "table_index": 1,
  "row_count": 6,
  "column_count": 3,
  "headers": ["Company", "Contact", "Country"],
  "rows": [
    {
      "Company": "Alfreds Futterkiste",
      "Contact": "Maria Anders",
      "Country": "Germany"
    }
  ]
}
```

### Use cases

- SEO and content audits: collect tables from competitor pages, documentation, pricing pages, and comparison articles.
- Research automation: turn public statistical tables into CSV without manual spreadsheet cleanup.
- Monitoring: schedule repeated runs against pages that update tables weekly or monthly.
- Data enrichment: combine extracted tables with other Apify actors in Make, Zapier, n8n, or your own API workflow.

### Practical tips

Start with a small URL list and inspect the first run before scaling. Some websites place layout tables, navigation tables, or hidden accessibility tables before the useful data table. The `table_index`, `headers`, `row_count`, and `column_count` fields help you identify which table you want. If you need only one table from a page, set `maxTables` low to reduce output noise.

For best results, target URLs that return the finished table in the initial HTML. Public reference pages, government sites, documentation pages, and old-style report pages usually work very well. Pages that load table rows from a JSON API after the browser opens may require a site-specific API actor or a browser actor.

### Reliability and performance

The actor intentionally avoids browser rendering and heavy dependencies. That makes it inexpensive, fast to start, and suitable for Apify schedules. It follows redirects, uses a normal browser-like user agent, limits the parsed HTML size to keep memory predictable, and continues with the next URL if one page fails.

### FAQ

**Does it handle multiple tables on one page?** Yes. Each table becomes one dataset item with its own `table_index`.

**Does it keep the table headers?** Yes when the first row uses `<th>` cells. If not, the actor creates `column_1`, `column_2`, and so on.

**Does it use a browser?** No. It uses direct HTTP requests for speed and reliability.

**Can it scrape JavaScript-rendered tables?** Only if the table appears in the HTML response. For fully client-rendered pages, use a browser actor or the site's API.

**Can I export the result to Excel?** Yes. Apify datasets export to JSON, CSV, Excel, XML, and RSS.

**Can I run it on a schedule?** Yes. Add the actor to an Apify schedule and point it at the URLs you want to monitor.

**Is it legal?** The actor reads public web pages. You are responsible for respecting website terms, robots directives, rate limits, and applicable privacy laws.

**What if a table has merged cells?** The actor extracts visible cell text into the row order. Complex rowspans and colspans may need post-processing.

**How is billing calculated?** Pay-per-event billing charges once per extracted table pushed to the dataset.

**Can it preserve links inside cells?** This version extracts visible text. If you need link-level extraction from table cells, combine it with a custom follow-up step or request a tailored version.

**Can I use it for competitor price tables?** Yes, as long as the table is public and present in the HTML response.

### You might also like

- Website Contact Extractor
- Meta Tags Extractor
- Schema Markup Extractor
- Webpage Text Extractor
- Sitemap URL Extractor

**Keywords:** html table scraper, table extractor, scrape tables, web table to csv, html to json, table parser, data extraction, public data scraper, spreadsheet automation, website data extraction, Apify table scraper, no code scraper, SEO tools, research automation, structured data extraction

# Actor input Schema

## `urls` (type: `array`):

Web pages to scan for HTML tables.

## `maxTables` (type: `integer`):

Maximum number of tables to return from each page.

## Actor input object example

```json
{
  "urls": [
    "https://www.w3schools.com/html/html_tables.asp"
  ],
  "maxTables": 3
}
```

# 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 = {
    "urls": [
        "https://www.w3schools.com/html/html_tables.asp"
    ],
    "maxTables": 3
};

// Run the Actor and wait for it to finish
const run = await client.actor("benthepythondev/html-table-extractor").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 = {
    "urls": ["https://www.w3schools.com/html/html_tables.asp"],
    "maxTables": 3,
}

# Run the Actor and wait for it to finish
run = client.actor("benthepythondev/html-table-extractor").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "urls": [
    "https://www.w3schools.com/html/html_tables.asp"
  ],
  "maxTables": 3
}' |
apify call benthepythondev/html-table-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=benthepythondev/html-table-extractor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "HTML Table Extractor",
        "description": "Extract structured rows from HTML tables on any web page.",
        "version": "1.0",
        "x-build-id": "xHJxYv94JIv46wt25"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/benthepythondev~html-table-extractor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-benthepythondev-html-table-extractor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/benthepythondev~html-table-extractor/runs": {
            "post": {
                "operationId": "runs-sync-benthepythondev-html-table-extractor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/benthepythondev~html-table-extractor/run-sync": {
            "post": {
                "operationId": "run-sync-benthepythondev-html-table-extractor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "urls": {
                        "title": "URLs",
                        "type": "array",
                        "description": "Web pages to scan for HTML tables.",
                        "default": [
                            "https://www.w3schools.com/html/html_tables.asp"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxTables": {
                        "title": "Max tables per URL",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "Maximum number of tables to return from each page.",
                        "default": 10
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
