# Stealth Scraper (`shvmgrx/stealth-scraper`) Actor

- **URL**: https://apify.com/shvmgrx/stealth-scraper.md
- **Developed by:** [Shivam Goraksha](https://apify.com/shvmgrx) (community)
- **Categories:** Lead generation, Developer tools, Automation
- **Stats:** 51 total users, 7 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## Stealth HTML Scraper

**Get fully rendered HTML from any website — even behind Cloudflare, Turnstile, Akamai, and other anti-bot protections.**

No browser setup. No proxy headaches. No blocked requests. Just pass a URL, get back the complete rendered HTML.

### The problem

You need HTML from a website. You send a request. You get back an empty shell, a CAPTCHA wall, or a 403. The site uses JavaScript rendering, anti-bot detection, or both — and your scraper is dead in the water.

This Actor fixes that permanently.

### Two modes for every situation

#### Stealth Mode (default)

A full browser renders the page exactly like a real user would see it. Every script executes, every API call fires, every component loads. The output is the complete, final HTML after all JavaScript has finished running.

Built from the ground up to be undetectable:

- **Automation fingerprints eliminated at the binary level** — not patched over with JavaScript hacks that bot detectors catch in milliseconds
- **Unique browser identity per request** — realistic fingerprints that pass canvas, WebGL, and font enumeration checks
- **WebRTC leak protection** — your real IP stays hidden even without proxies
- **Canvas fingerprint randomization** — defeats the most common browser fingerprinting technique
- **Passes Cloudflare Turnstile, Akamai Bot Manager, PerimeterX, DataDome**, and every other major anti-bot system

Use stealth mode for:

- Cloudflare-protected sites
- Single-page applications (React, Vue, Angular, Next.js)
- Sites that return empty HTML to regular HTTP requests
- Any page where you need the fully rendered DOM

#### Fast Mode

Lightning-fast HTTP requests with intelligent header and connection fingerprinting. No browser overhead — just raw speed. 10x faster and 10x cheaper than stealth mode.

Use fast mode for:

- Static websites, blogs, and documentation
- REST APIs and JSON endpoints
- Sites without bot protection
- High-volume jobs where speed matters more than rendering

### Who this is for

#### Lead generation teams

Scrape business directories, agent profiles, company pages, and contact databases — even when they're locked behind anti-bot walls. Get the rendered HTML with all the data your pipeline needs.

#### Price monitoring & competitive intelligence

Track competitor pricing, inventory levels, and product catalogs on e-commerce sites. Works on Shopify, Amazon, and other platforms that aggressively block scrapers.

#### Real estate & property data

Pull fully rendered listing pages, agent profiles, and property details from MLS sites and real estate platforms that rely on JavaScript rendering.

#### Market research & analytics

Collect rendered data from review sites, social platforms, job boards, and financial data providers. Get the same HTML a real browser sees — no missing content.

#### SEO & content monitoring

Check how pages actually render to search engines. Capture dynamically loaded content, lazy-loaded images, and client-side rendered text that static scrapers miss entirely.

#### Academic & research data collection

Gather datasets from web sources at scale without getting blocked. Ideal for researchers who need reliable, repeatable access to public web data.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `urls` | string\[] | *required* | List of URLs to scrape |
| `mode` | string | `"stealth"` | `"stealth"` (full browser rendering) or `"fast"` (HTTP only) |
| `concurrency` | integer | `5` | Parallel pages (1-20) |
| `timeout` | integer | `60` | Seconds per page |
| `delay` | number | `2` | Seconds between requests per slot |
| `waitSelector` | string | `null` | CSS selector to wait for before capturing HTML |
| `networkIdle` | boolean | `true` | Wait for all network requests to finish |
| `blockWebrtc` | boolean | `true` | Prevent IP leaks through WebRTC |
| `hideCanvas` | boolean | `true` | Randomize canvas fingerprint |
| `useProxy` | boolean | `false` | Route through Apify residential proxies |
| `proxyGroups` | string\[] | `["RESIDENTIAL"]` | Proxy groups to use |

### Output

Each URL produces a dataset row:

```json
{
    "url": "https://example.com/page",
    "status": 200,
    "html": "<!DOCTYPE html><html>...</html>",
    "bytes": 875432,
    "error": null
}
```

The `html` field contains the full rendered DOM — ready to parse with any HTML parser in any language.

### Examples

#### Scrape a protected page

```json
{
    "urls": ["https://protected-site.com/data"],
    "mode": "stealth",
    "useProxy": true,
    "networkIdle": true
}
```

#### Bulk scrape 1,000 product pages

```json
{
    "urls": ["https://shop.com/product/1", "https://shop.com/product/2", "..."],
    "mode": "fast",
    "concurrency": 15,
    "delay": 1
}
```

#### Wait for dynamic content to load

```json
{
    "urls": ["https://spa-app.com/dashboard"],
    "mode": "stealth",
    "waitSelector": ".dashboard-content",
    "networkIdle": true
}
```

### API integration

Call this Actor programmatically from any language:

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("YOUR_USERNAME/stealth-scraper").call(
    run_input={"urls": ["https://example.com/"], "mode": "stealth"}
)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["url"], item["bytes"], "bytes")
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_API_TOKEN' });

const run = await client.actor('YOUR_USERNAME/stealth-scraper').call({
    urls: ['https://example.com/'],
    mode: 'stealth',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Performance

| Mode | Speed | Cost | Best for |
|------|-------|------|----------|
| **Fast** | ~1-2 sec/page | Fractions of a cent | Static sites, APIs, bulk jobs |
| **Stealth** | ~5-10 sec/page | ~$0.01-0.03/page | JS-rendered sites, anti-bot protected |

Run 15 pages in parallel and process **5,000+ pages per hour** in stealth mode.

### FAQ

**Will this work on my target site?**
If it loads in a real browser, this Actor can scrape it. It passes every major bot detection system in production today.

**Do I need proxies?**
For most sites, no. For sites that rate-limit by IP or block datacenter IPs, enable Apify residential proxies for best results.

**Can I scrape thousands of pages?**
Yes. Set concurrency to 10-15 and let it run. The Actor handles errors gracefully and processes pages in parallel.

**What do I get back?**
The exact same HTML that a real user's browser would render — including all JavaScript-generated content, dynamically loaded data, and client-side rendered components.

**How is this different from other scraping actors?**
Most scrapers use standard headless browsers that get detected and blocked immediately. This Actor uses a purpose-built stealth engine that eliminates automation fingerprints at a fundamental level — not through surface-level patches that bot detectors are designed to catch.

# Actor input Schema

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

List of URLs to fetch rendered HTML from.

## `mode` (type: `string`):

"fast" uses plain HTTP (no JS, cheap). "stealth" uses a full stealth browser with anti-bot bypass (JS rendered, more expensive).

## `concurrency` (type: `integer`):

Number of pages to scrape in parallel. Max 20.

## `timeout` (type: `integer`):

Max seconds to wait per page.

## `delay` (type: `number`):

Seconds to wait between requests per concurrent slot.

## `waitSelector` (type: `string`):

Optional CSS selector to wait for before capturing HTML. e.g. ".content-loaded"

## `networkIdle` (type: `boolean`):

Wait for 500ms of no network activity before capturing. Recommended for JS-heavy sites.

## `blockWebrtc` (type: `boolean`):

Prevent IP leaks through WebRTC when using proxies.

## `hideCanvas` (type: `boolean`):

Inject noise into canvas fingerprinting to avoid detection.

## `useProxy` (type: `boolean`):

Route requests through Apify residential proxies. Recommended for anti-bot protected sites.

## `proxyGroups` (type: `array`):

Apify proxy groups to use. Defaults to RESIDENTIAL.

## Actor input object example

```json
{
  "urls": [
    "https://www.example.com/"
  ],
  "mode": "stealth",
  "concurrency": 5,
  "timeout": 60,
  "delay": 2,
  "networkIdle": true,
  "blockWebrtc": true,
  "hideCanvas": true,
  "useProxy": false,
  "proxyGroups": [
    "RESIDENTIAL"
  ]
}
```

# 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.example.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("shvmgrx/stealth-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 = { "urls": ["https://www.example.com/"] }

# Run the Actor and wait for it to finish
run = client.actor("shvmgrx/stealth-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 '{
  "urls": [
    "https://www.example.com/"
  ]
}' |
apify call shvmgrx/stealth-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,shvmgrx/stealth-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/2Ct5cErqA1JsImN2R/builds/bP4aAMWwI1lFNy2Wi/openapi.json
