Firecrawl API — облачный сервис, который по адресу страницы возвращает её содержимое в виде markdown, HTML или структурированного JSON, а по адресу сайта обходит страницы заданием и отдаёт их пачкой. Скрипт на вашей стороне готовит список адресов, вызывает сервис и проверяет ответ, а языковая модель получает уже очищенный текст для пересказа или извлечения полей. Страницы без права на сбор остаются за рамками схемы: в неё попадают собственный сайт, партнёрские материалы с разрешением и открытые документы с понятной лицензией.
Что делает сервис
Основной вызов — POST https://api.firecrawl.dev/v2/scrape с ключом в заголовке Authorization; в ответе приходят содержимое страницы в запрошенных форматах и метаданные, включая код ответа сайта.
Документация Firecrawl описывает несколько режимов: scrape извлекает одну страницу, crawl рекурсивно обходит сайт, map собирает список адресов, search ищет в сети и возвращает содержимое найденных страниц. Это сервис обхода и извлечения: он сам открывает страницы и очищает вёрстку. Подключение таких операций к ИИ-клиенту через протокол MCP — отдельная тема, а здесь описан прямой вызов API из вашего скрипта, где каждый шаг виден и проверяем.
Исходный код проекта открыт и опубликован под лицензией AGPL-3.0, поэтому сервис можно развернуть у себя. Облачный вариант удобнее в запуске, зато страницы и запросы проходят через внешнюю инфраструктуру. Для данных, которые нельзя передавать наружу, выбирайте собственный сервер или другой способ сбора; условия AGPL перед встраиванием в продукт сверьте с юристом.
Центр тяжести здесь в получении чистого содержимого страниц: структурное извлечение полей есть, но служит дополнением. У библиотеки ScrapeGraphAI центр другой: запрос к языковой модели составляет ядро конвейера, и работает она на вашей стороне.
Список адресов
Начните с таблицы разрешённых адресов: URL, владелец страницы, основание для сбора, периодичность и поле, которое вам нужно. Основание фиксируется словами: «наш сайт», «письменное согласие партнёра», «открытая лицензия». Страницы с персональными данными, закрытые разделы и материалы, где правила сайта запрещают автоматический сбор, остаются за пределами списка. Правила сайта, файл robots.txt, авторские права на тексты и закон о персональных данных относятся к вашей ответственности, а спорные случаи решает юрист компании.
Режим crawl удобен, когда нужно пройти весь раздел собственного сайта. Запрос POST /v2/crawl возвращает идентификатор задания, статус читается через GET /v2/crawl/{id}, а завершение можно получать вебхуком. Ограничивайте обход параметром limit и шаблонами includePaths и excludePaths, чтобы задание осталось в нужной части сайта. По документации, сервис учитывает robots.txt, а отключение этой проверки доступно только в корпоративном плане; закладывать его в план нельзя.
Для первого теста удобнее режим map: он возвращает адреса, найденные на сайте, и вы сверяете их с картой сайта и с тем, что знает редактор. Лишние адреса удаляйте из списка до первого массового вызова.
Структура результата
Ответ scrape содержит признак успеха и объект data. Внутри лежат запрошенные форматы, например markdown и html, и объект metadata с заголовком, адресом и полем statusCode. Параметр onlyMainContent по умолчанию включён и отбрасывает шапку и подвал, так что в текст попадает основная часть страницы. Нужный формат задаётся списком formats, поэтому запрашивайте только то, что обработает ваш скрипт.
| Поле | Что означает | Что проверяет скрипт |
|---|---|---|
| success | Сервис выполнил запрос | Значение true, иначе запись уходит в очередь ошибок |
| data.markdown | Очищенный текст страницы | Длина выше порога, заголовок совпадает с ожидаемым |
| metadata.statusCode | Код ответа самого сайта | Значение 200; другие коды фиксируются отдельно |
| metadata.title и адрес страницы | Заголовок и адрес из метаданных ответа | Адрес совпадает с запрошенным или есть объяснение переадресации |
Если нужны поля вместо текста, режим JSON принимает схему, и результат приходит в заданной структуре. Схему описывайте узко: название, цена, дата, ссылка. Пустое поле остаётся пустым, домысливать значение модели нельзя, а скрипт отмечает такую запись для ручной проверки. Полный текст страницы хранится у вас, ссылка на источник стоит рядом с каждым полем.
Какие поля вы хотите получать со страниц своего сайта?
Ошибки и свежесть
Документация перечисляет коды ответов API: 400 для неверных параметров, 402 при нехватке кредитов, 429 при превышении лимита и 5xx для сбоев на стороне сервиса; другие коды, например 403 или 409, ищите в справочнике по ошибкам. Каждый код требует своей реакции. Ошибку параметров исправляют в запросе, 402 сообщают владельцу аккаунта, 429 и 5xx повторяют с растущей паузой и верхней границей попыток.
Отдельный вопрос — свежесть. Параметр maxAge задаёт допустимый возраст кешированной копии в миллисекундах, по умолчанию это двое суток, поэтому сервис иногда отдаёт сохранённую версию страницы вместо свежей. Для цены и наличия задавайте малый возраст или требуйте свежий запрос, для статей и документации допустим более долгий. Результаты crawl, по документации, доступны через API в течение суток после завершения, поэтому скрипт забирает их сразу и складывает у себя.
Стоимость вызовов в Firecrawl считается в кредитах, и разные режимы и форматы могут расходовать их по-разному. Актуальные цифры смотрите на странице тарифов вендора. Практический вывод: сначала получайте markdown, а структурное извлечение включайте только для тех страниц, где оно нужно, и держите дневной потолок вызовов в самом скрипте.
Ошибки отдельных страниц внутри задания crawl читаются отдельным вызовом списка ошибок. Страницу, которая вернула пустой текст либо код, отличный от 200, извлечённой считать нельзя: она уходит в журнал с адресом и временем, а повторная попытка планируется на следующий цикл. В журнал записывают адрес, режим, код, длину текста и версию схемы. Содержимое страниц с персональными данными в журнале отсутствует.
Тест на сайте
- Выберите двадцать страниц собственного сайта: статьи, карточки услуг, страницы с таблицами и пару заведомо сложных, с динамическим содержимым.
- Вызовите scrape для каждой страницы с форматом markdown и сохраните ответ вместе с кодом.
- Откройте страницы в браузере и сравните: заголовок, абзацы, таблицы, ссылки. Отметьте потери и лишний текст.
- Запустите crawl одного раздела с малым лимитом и сверьте число страниц с картой сайта.
- Повторите вызов через сутки и сравните: изменился ли текст там, где редактор правок вносил.
Разделение ролей держите жёстким. Скрипт хранит полные страницы, считает хеши текста и находит изменения между обходами. Модель получает только изменившиеся фрагменты и объясняет, что поменялось. Человек сверяет объяснение с источником и принимает решение. Так сервис обхода остаётся поставщиком данных, а отчёт для команды опирается на проверяемый текст, который можно открыть по ссылке и прочитать целиком.
Условный пример: компания ведёт каталог услуг и хочет раз в неделю сверять описание на сайте с внутренним прайс-листом. Скрипт берёт адреса из таблицы, получает текст страниц и вытаскивает названия и сроки по узкой схеме. Различия между сайтом и прайс-листом попадают в отчёт для редактора, а правку вносит человек. Модель здесь формулирует краткое описание расхождения, решение о публикации остаётся за сотрудником.
Итог теста — таблица расхождений и решение, какие страницы пригодны для автоматического сбора. Модель подключают после этого шага: она получает очищенный текст и формулирует пересказ или заполняет поля, а скрипт проверяет, что каждое поле подкреплено фрагментом источника. Для задач поиска и проверки источников пригодится материал про браузер под управлением ИИ-агента, а для регулярных выгрузок в учётные системы — страница про автоматизацию бизнес-процессов.
Составьте список из двадцати своих страниц с основанием для сбора и прогоните его через scrape. Пока расхождения с браузером остаются необъяснёнными, crawl на весь сайт запускать рано.