Скрейпинг (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
- Сценарий: быстрое понимание, дайджесты
- Когда: агрегация новостей, исследования, курация
links
- Описание: все ссылки со страницы массивом строк
- Сценарий: обнаружение ссылок, подготовка к 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"
}
}Рекомендации
Выбор движка
- Не уверены / универсально →
auto(по умолчанию) — сервер сам выбирает движок - Статический контент (новости, блоги, документация) →
cheerio - Сложные SPA с JS →
playwrightили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 поддерживает высокую параллельность. Можно отправлять много запросов одновременно; ответы приходят сразу.