AnyCrawl

Скрейпинг (Scrape)

Скрейпинг URL и преобразование в структурированные данные для LLM.

Введение

Scrape API AnyCrawl превращает любую веб-страницу в структурированные данные для больших языковых моделей (LLM). Поддерживаются движки Cheerio, Playwright, Puppeteer и форматы HTML, Markdown, JSON и др.

Ключевые возможности: API отвечает сразу синхронно — без опроса и вебхуков. Также нативно поддерживается высокая параллельность для массового скрейпинга.

Основные возможности

  • Несколько движков: auto (умный выбор по умолчанию), cheerio (статический HTML, самый быстрый), playwright (JS в разных браузерах), puppeteer (JS под Chrome)
  • Оптимизация под LLM: автоматическое извлечение и форматирование, Markdown для удобной обработки LLM
  • Прокси: HTTP/HTTPS
  • Надёжность: обработка ошибок и повторы
  • Производительность: высокая параллельность с асинхронной очередью
  • Синхронный ответ: результаты сразу, без опроса

Конечная точка API

POST https://api.anycrawl.dev/v1/scrape

Примеры

cURL

Базовый скрейпинг (движок auto по умолчанию)

curl -X POST "https://api.anycrawl.dev/v1/scrape" \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com"
  }'

Динамический контент с движком Playwright

curl -X POST "https://api.anycrawl.dev/v1/scrape" \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://spa-example.com",
    "engine": "playwright"
  }'

Скрейпинг через прокси

curl -X POST "https://api.anycrawl.dev/v1/scrape" \
  -H "Authorization: Bearer <your-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "engine": "playwright",
    "proxy": "http://proxy.example.com:8080"
  }'

Параметры запроса

| Parameter | Type | Required | Default | Description | | ------------------- | ------------------------ | -------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | url | string | Yes | - | URL для скрейпинга; допустимы только HTTP/HTTPS | | template_id | string | No | - | ID шаблона для этого скрейпа | | variables | object | No | - | Переменные шаблона (только с template_id) | | engine | enum | No | auto | Тип движка: auto, cheerio, playwright, puppeteer | | formats | array | No | ["markdown"] | Форматы вывода: markdown, html, text, screenshot, screenshot@fullPage, rawHtml, json, summary, links | | timeout | number | No | 60000 | Таймаут (мс). Если не задан: 120000 при proxy=stealth / proxy=auto; иначе 60000. | | retry | boolean | No | false | Повтор при ошибке | | max_age | number | No | - | Макс. возраст кэша (мс). 0 — без чтения кэша; не указано — по умолчанию сервера | | store_in_cache | boolean | No | true | Записывать ли Page Cache для этого скрейпа | | wait_for | number | No | - | Задержка перед извлечением (мс); только браузерные движки; ниже приоритета, чем wait_for_selector | | wait_until | enum | No | - | Условие навигации для браузера: load, domcontentloaded, networkidle, commit | | wait_for_selector | string, object, or array | No | - | Wait for one or multiple selectors (browser engines only). Accepts a CSS selector string, an object { selector: string, state?: "attached" | "visible" | "hidden" | "detached", timeout?: number }, or an array mixing strings/objects. Each entry is awaited sequentially. Takes priority over wait_for. | | include_tags | array | No | - | Включаемые теги, например: h1 | | exclude_tags | array | No | - | Исключаемые теги, например: h1 | | only_main_content | boolean | No | true | Только основной контент, без шапки/подвала/навигации (приоритет у include_tags) | | proxy | string (URI) | No | - | Адрес прокси: http://proxy:port или https://proxy:port | | json_options | json | No | - | Параметры JSON, например: {"schema": {}, "user_prompt": "Extract key fields"} | | extract_source | enum | No | markdown | Источник для JSON: markdown (по умолчанию) или html | | ocr_options | boolean | No | false | OCR для картинок в markdown; не меняет html/rawHtml |

Поведение кэша

  • max_age управляет чтением кэша. 0 — принудительное обновление.
  • store_in_cache=false отключает запись в кэш.
  • При попадании в кэш в ответе есть cachedAt и maxAge (мс).

Типы движков

Важно: и playwright, и puppeteer могут использовать Chromium, но назначение и возможности разные.

auto (по умолчанию)

  • Сценарий: неизвестно, какой движок лучше для страницы
  • Плюсы: анализ страницы и выбор движка — cheerio для статики, playwright для тяжёлого JS
  • Как работает: сначала лёгкий HTTP-запрос; при необходимости JS — переход на браузерный движок
  • Когда использовать: универсальный скрейпинг без ручного выбора движка

cheerio

  • Сценарий: статический HTML
  • Плюсы: максимальная скорость, минимум ресурсов
  • Ограничения: нет выполнения JavaScript и динамики
  • Когда: статьи, блоги, статические сайты

playwright

  • Сценарий: современные сайты с JS, кросс-браузерное тестирование
  • Плюсы: ожидания и стабильность
  • Ограничения: выше расход ресурсов
  • Когда: сложные веб-приложения

puppeteer

  • Плюсы: интеграция с Chrome DevTools, метрики, скорость
  • Ограничения: нет поддержки архитектуры ARM

Форматы вывода

Список форматов задаётся параметром formats:

markdown

  • Описание: чистый структурированный Markdown из HTML
  • Сценарий: LLM, документация, анализ контента
  • Когда: много текста, статьи, блоги

html

  • Описание: очищенный и отформатированный HTML
  • Сценарий: нужна структура HTML с вёрсткой
  • Когда: контент с сохранением HTML-структуры

text

  • Описание: plain text без разметки
  • Сценарий: простое извлечение текста
  • Когда: только текст, ключевые слова

screenshot

  • Описание: скриншот видимой области
  • Сценарий: визуальное представление страницы
  • Ограничения: только playwright и puppeteer
  • Когда: проверка UI, визуальная верификация

screenshot@fullPage

  • Описание: скриншот всей страницы, включая ниже сгиба
  • Сценарий: полный визуальный снимок
  • Ограничения: только playwright и puppeteer
  • Когда: документация страницы, архив

rawHtml

  • Описание: исходный HTML без постобработки
  • Сценарий: точный ответ сервера
  • Когда: отладка, анализ, сохранение исходной структуры

summary

  • Описание: краткое резюме контента страницы с помощью AI
  • Сценарий: быстрое понимание, дайджесты
  • Когда: агрегация новостей, исследования, курация
  • Описание: все ссылки со страницы массивом строк
  • Сценарий: обнаружение ссылок, подготовка к crawl, анализ
  • Особенности: относительные URL → абсолютные, без дубликатов и фрагментов
  • Когда: краулеры, структура сайта, связанные страницы

Объект json_options

Параметр json_options — объект со следующими полями:

  • schema: схема извлечения
  • user_prompt: пользовательская подсказка
  • schema_name: необязательное имя выходных данных
  • schema_description: необязательное описание выходных данных

Пример

{
    "schema": {},
    "user_prompt": "Extract the title and content of the page"
}

or

{
    "schema": {
        "type": "object",
        "properties": {
            "title": {
                "type": "string"
            },
            "company_name": {
                "type": "string"
            },
            "summary": {
                "type": "string"
            },
            "is_open_source": {
                "type": "boolean"
            }
        },
        "required": ["company_name", "summary"]
    },
    "user_prompt": "Extract the company name, summary, and if it is open source"
}

Формат ответа

Успешный ответ (HTTP 200)

Успешный скрейпинг

{
    "success": true,
    "data": {
        "url": "https://mock.httpstatus.io/200",
        "status": "completed",
        "jobId": "c9fb76c4-2d7b-41f9-9141-b9ec9af58b39",
        "title": "",
        "metadata": [
            {
                "name": "color-scheme",
                "content": "light dark"
            }
        ],
        "html": "<html><head><meta name=\"color-scheme\" content=\"light dark\"></head><body><pre style=\"word-wrap: break-word; white-space: pre-wrap;\">200 OK</pre></body></html>",
        "screenshot": "http://localhost:8080/v1/public/storage/file/screenshot-c9fb76c4-2d7b-41f9-9141-b9ec9af58b39.jpeg",
        "timestamp": "2025-07-01T04:38:02.951Z"
    }
}

Ответ из кэша

{
    "success": true,
    "data": {
        "url": "https://example.com",
        "status": "completed",
        "jobId": "c9fb76c4-2d7b-41f9-9141-b9ec9af58b39",
        "cachedAt": "2026-02-08T12:34:56.000Z",
        "maxAge": 172800000
    }
}

Ответы с ошибками

400 — ошибка валидации

{
    "success": false,
    "error": "Validation error",
    "details": {
        "issues": [
            {
                "field": "engine",
                "message": "Invalid enum value. Expected 'auto' | 'playwright' | 'cheerio' | 'puppeteer', received 'invalid'",
                "code": "invalid_enum_value"
            }
        ],
        "messages": [
            "Invalid enum value. Expected 'auto' | 'playwright' | 'cheerio' | 'puppeteer', received 'invalid'"
        ]
    }
}

401 — ошибка аутентификации

{
    "success": false,
    "error": "Invalid API key"
}

Неудачный скрейпинг

{
    "success": false,
    "error": "Scrape task failed",
    "message": "Page is not available: 404 ",
    "data": {
        "url": "https://mock.httpstatus.io/404",
        "status": "failed",
        "type": "http_error",
        "message": "Page is not available: 404 ",
        "code": 404,
        "metadata": [
            {
                "name": "color-scheme",
                "content": "light dark"
            }
        ],
        "jobId": "34cd1d26-eb83-40ce-9d63-3be1a901f4a3",
        "title": "",
        "html": "<html><head><meta name=\"color-scheme\" content=\"light dark\"></head><body><pre style=\"word-wrap: break-word; white-space: pre-wrap;\">404 Not Found</pre></body></html>",
        "screenshot": "screenshot-34cd1d26-eb83-40ce-9d63-3be1a901f4a3.jpeg",
        "timestamp": "2025-07-01T04:36:20.978Z",
        "statusCode": 404,
        "statusMessage": ""
    }
}

or

{
    "success": false,
    "error": "Scrape task failed",
    "message": "Page is not available: 502 ",
    "data": {
        "url": "https://mock.httpstatus.io/502",
        "status": "failed",
        "type": "http_error",
        "message": "Page is not available: 502 ",
        "code": 502,
        "metadata": [
            {
                "name": "color-scheme",
                "content": "light dark"
            }
        ],
        "jobId": "5fc50008-07e0-4913-a6af-53b0b3e0214b",
        "title": "",
        "html": "<html><head><meta name=\"color-scheme\" content=\"light dark\"></head><body><pre style=\"word-wrap: break-word; white-space: pre-wrap;\">502 Bad Gateway</pre></body></html>",
        "screenshot": "screenshot-5fc50008-07e0-4913-a6af-53b0b3e0214b.jpeg",
        "timestamp": "2025-07-01T04:39:59.981Z",
        "statusCode": 502,
        "statusMessage": ""
    }
}

or

{
    "success": false,
    "error": "Scrape task failed",
    "message": "Page is not available: 400 ",
    "data": {
        "url": "https://mock.httpstatus.io/400",
        "status": "failed",
        "type": "http_error",
        "message": "Page is not available: 400 ",
        "code": 400,
        "metadata": [
            {
                "name": "color-scheme",
                "content": "light dark"
            }
        ],
        "jobId": "0081747c-1fc5-44f9-800c-e27b24b55a2c",
        "title": "",
        "html": "<html><head><meta name=\"color-scheme\" content=\"light dark\"></head><body><pre style=\"word-wrap: break-word; white-space: pre-wrap;\">400 Bad Request</pre></body></html>",
        "screenshot": "screenshot-0081747c-1fc5-44f9-800c-e27b24b55a2c.jpeg",
        "timestamp": "2025-07-01T04:38:24.136Z",
        "statusCode": 400,
        "statusMessage": ""
    }
}

or

{
    "success": false,
    "error": "Scrape task failed",
    "message": "Page is not available",
    "data": {
        "url": "https://httpstat.us/401",
        "status": "failed",
        "type": "http_error",
        "message": "Page is not available"
    }
}

Рекомендации

Выбор движка

  1. Не уверены / универсальноauto (по умолчанию) — сервер сам выбирает движок
  2. Статический контент (новости, блоги, документация) → cheerio
  3. Сложные SPA с JSplaywright или puppeteer

Производительность

  • Для массового статического контента отдавайте предпочтение cheerio
  • playwright или puppeteer — только когда нужен рендеринг JS
  • Для стабильности используйте ротацию прокси против блокировок; прокси должны быть надёжными
  • Используйте высокую параллельность — API эффективно обрабатывает много одновременных запросов

Обработка ошибок

try {
    const response = await fetch("/v1/scrape", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ url: "https://example.com" }),
    });

    const result = await response.json();

    if (result.success && result.data.status === "completed") {
        // Handle successful result
        console.log(result.data.markdown);
    } else {
        // Handle scraping failure
        console.error("Scraping failed:", result.data.error);
    }
} catch (error) {
    // Handle network error
    console.error("Request failed:", error);
}

Высокая параллельность

API поддерживает высокую параллельность. Можно отправлять много одновременных запросов без искусственного лимита частоты:

// Concurrent scraping example
const urls = ["https://example1.com", "https://example2.com", "https://example3.com"];

const scrapePromises = urls.map((url) =>
    fetch("/v1/scrape", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ url, engine: "cheerio" }),
    }).then((res) => res.json())
);

// All requests execute concurrently and return immediately
const results = await Promise.all(scrapePromises);

Частые вопросы

Когда использовать разные движки?

У каждого движка свои сильные стороны:

  • Auto (по умолчанию): выбирает движок по URL — быстрый старт с Cheerio и переход на Playwright при необходимости JS
  • Cheerio: статический HTML, максимальная скорость, без выполнения JS
  • Playwright: сложные приложения, стабильность и ожидания; в будущем — больше типов браузеров
  • Puppeteer: только Chrome/Chromium, не работает на ARM; отдельные образы Docker для ARM не предоставляются

Почему часть сайтов не скрейпится?

Возможные причины:

  • сайт блокирует краулеров (403/404)
  • нужен JS, а выбран cheerio
  • нужна авторизация или особые заголовки
  • проблемы сети

Как быть с сайтами с входом?

Сейчас API не поддерживает аутентификацию пользователя. Рекомендации:

  • скрейпить публичные страницы
  • получать контент с авторизацией другими способами

Какие требования к прокси?

  • По умолчанию доступен качественный прокси; свой прокси не обязателен без особых требований
  • Поддерживаются HTTP/HTTPS
  • Формат: http://host:port или https://host:port
  • Прокси должны быть стабильными и доступными

Есть ли лимит на параллельные запросы?

Нет, API поддерживает высокую параллельность. Можно отправлять много запросов одновременно; ответы приходят сразу.