Публичная бизнес-страница Facebook является полезным источником сигналов: бренд публикует там посты, покупатели реагируют на них, а метаданные страницы (название, текст описания, недавние публичные посты и публичные счётчики реакций и комментариев), это именно те данные, которые питают исследование конкурентов, анализ контента и мониторинг бренда. Проблема в том, что Facebook рендерит почти всё на стороне клиента с помощью JavaScript и AJAX, и агрессивно противодействует автоматизированному трафику, поэтому простой HTTP-запрос возвращает почти пустую оболочку загрузчика вместо контента, который вы видите в браузере.
Это руководство показывает, как извлекать данные из публичной страницы Facebook с помощью JavaScript и Node.js через Crawling API. Вы создадите небольшой, запускаемый скрипт, который загружает отрендеренную публичную бизнес-страницу и извлекает поля уровня страницы: название страницы, текст публичных постов и публичные счётчики вовлечённости. Всё руководство ограничено исключительно публичными бизнес-страницами и страницами брендов. Оно не касается личных профилей, закрытых групп, комментариев, привязанных к идентифицируемым людям, или чего-либо за логином. Раздел о законности и конфиденциальности находится ближе к началу статьи не случайно, поэтому прочитайте его прежде, чем направить это на что-либо.
Условия использования Facebook строго ограничивают автоматизированный сбор данных, и большая часть платформы является персональными данными. Воспринимайте это как образовательное руководство только по публичным данным. Для любого реального проекта санкционированный путь, официальный Facebook Graph API, а не скрейпинг. Раздел «Законно ли скрейпить Facebook?» ниже, не формальность.
Что вы создадите
Скрипт Node.js, принимающий URL публичной бизнес-страницы Facebook, получающий отрендеренный HTML через Crawling API и возвращающий структурированную запись публичных данных уровня страницы. Мы будем использовать страницу известного бренда как рабочий пример и извлекать следующие поля:
- Название страницы, публичное отображаемое имя бизнеса или страницы бренда, например «Alibaba.com».
- Текст поста, публичный текст недавних постов, опубликованных самой страницей.
- Количество реакций, публичный итог реакций, показанных на каждом посте.
- Количество комментариев, публичное количество комментариев, показанных на каждом посте, только как агрегированный счётчик.
- Количество репостов, публичное количество репостов, показанных на каждом посте.
Обратите внимание на то, чего намеренно нет: ни имён комментаторов, ни текстов отдельных комментариев, ни данных профилей, ни списков подписчиков. Это персональные данные, выходящие за рамки. Мы агрегируем на уровне страницы и поста и останавливаемся на этом.
Почему простой запрос не работает с Facebook
Если запросить URL страницы Facebook через простой HTTP-клиент, вы получите технически успешный, но практически пустой ответ. Два фактора работают против вас.
Во-первых, Facebook строит страницу в браузере. Название страницы, раздел «О себе» и каждый пост загружаются динамически через JavaScript и AJAX-вызовы после поступления исходного документа, а дополнительные посты появляются только при прокрутке. Загрузите сырой URL, и вы в основном получите разметку для спиннеров загрузки, а не контент, отрендеренный вокруг них. Захват реальных данных означает ожидание разрешения этих AJAX-вызовов и симуляцию прокрутки, запускающей дополнительный контент.
Во-вторых, Facebook активно защищается от автоматизированного трафика. Он следит за IP-адресами, отмечает паттерны запросов, не похожие на реальный браузер, и применяет строгие ограничения скорости, которые могут привести к временной или постоянной блокировке. Датацентровый IP, бомбардирующий запросами в плотном цикле, это именно тот тип трафика, который система построена останавливать.
Итак, рабочий подход требует двух вещей в одном запросе: реального браузера, рендерящего страницу и ожидающего асинхронного контента, и IP, воспринимаемого платформой как обычный посетитель. Можно собрать это самостоятельно с безголовым браузером и пулом ротируемых резидентных прокси, но поддержание этого стека в рабочем состоянии составляет большую часть работы. Crawling API объединяет оба требования в один вызов: вы отправляете URL с JavaScript-токеном и правильными параметрами ожидания, он рендерит страницу за доверенным IP и возвращает готовый HTML или распарсенный JSON. О рендеринге сложных целей см. статью как краулить JavaScript-сайты.
Предварительные требования
Перед написанием кода нужно подготовить несколько вещей. Ни одна из них не займёт много времени.
Базовые знания JavaScript и Node.js. Вы должны уметь писать и запускать Node-скрипты и устанавливать пакеты с помощью npm. Если вы новичок, наше руководство о том, как создать веб-скрейпер с Node.js, охватывает основы, которые предполагает этот туториал.
Node.js 16 или новее. Подтвердите версию командой node --version. Если не установлен, установите с сайта Node.js или через менеджер версий, такой как nvm.
Аккаунт Crawlbase и JS-токен. Зарегистрируйтесь для получения бесплатного аккаунта, откройте панель управления и скопируйте JavaScript (JS) токен. Crawlbase даёт до 20 000 бесплатных запросов для начала, и вы платите только за успешные запросы. Facebook рендерится на стороне клиента, поэтому здесь нужен JavaScript-токен, а не обычный. Обращайтесь с токеном как с паролем и не помещайте его в систему контроля версий.
Настройка проекта
Создайте папку проекта, инициализируйте её и установите клиент Crawlbase для Node.
node --version mkdir facebook-page-scraper && cd facebook-page-scraper npm init -y npm install crawlbase
Пакет crawlbase является официальным Node-клиентом для Crawling API. Для демонстрации уровня страницы мы опираемся на встроенный скрейпер Crawlbase для страниц Facebook, возвращающий структурированный JSON, поэтому нам не нужен отдельный HTML-парсер для основного примера.
Шаг 1: загрузите отрендеренную публичную страницу
Начните с получения готовой страницы. Импортируйте класс CrawlingAPI, инициализируйте его вашим JS-токеном и запросите URL публичной бизнес-страницы. Параметры ожидания, это то, что вообще делает загрузку Facebook рабочей, поэтому они здесь важнее, чем на статичном сайте.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); // A PUBLIC business/brand Page only, never a personal profile or private group const pageUrl = 'https://www.facebook.com/Alibaba.comGlobal/'; async function fetchPage(url) { const options = { format: 'json', ajax_wait: 'true', scroll: 'true', scroll_interval: 30, }; const response = await api.get(url, options); if (response.statusCode === 200) { return JSON.parse(response.body); } console.error(`Request failed: ${response.statusCode}`); return null; } fetchPage(pageUrl).then((data) => { if (data) console.log(data.body.slice(0, 500)); });
Каждый параметр заслуживает своего места. format: 'json' запрашивает структурированный ответ, чтобы отрендеренный HTML поступал в поле body, а не как сырой документ. ajax_wait: 'true' указывает API удерживать до разрешения AJAX-вызовов страницы, что важно, поскольку Facebook загружает реальный контент именно так; пропустите, и захватите разметку загрузчика. scroll: 'true' симулирует прокрутку пользователя, загружая дополнительные посты, а scroll_interval устанавливает время прокрутки в секундах (максимум 60). Запустите скрипт командой node script.js и в срезе должна появиться реальная разметка страницы, а не урезанная оболочка. Это подтверждает, что рендеринг работает, прежде чем вы что-либо парсите.
Единственный вызов api.get сделал то, для чего иначе понадобились бы безголовый браузер и пул прокси. Crawling API рендерит страницу в реальном браузере, ждёт AJAX-вызовов с помощью ajax_wait, симулирует прокрутку для загрузки большего количества постов и ротирует резидентные IP на сервере, чтобы не нужно было разворачивать и обслуживать весь этот стек. Начните с бесплатного уровня и направьте на публичную бизнес-страницу.
Шаг 2: получите структурированные данные страницы со встроенным скрейпером
Сырой HTML пригоден, но вам пришлось бы писать и поддерживать селекторы против часто меняющейся разметки Facebook. Crawling API поставляется со встроенным скрейпером facebook-page, возвращающим публичные данные страницы уже распарсенными как JSON, это правильный инструмент для извлечения на уровне страницы. Вы включаете его параметром scraper.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const pageUrl = 'https://www.facebook.com/Alibaba.comGlobal/'; async function scrapePage(url) { const options = { ajax_wait: 'true', scraper: 'facebook-page', }; const response = await api.get(url, options); if (response.statusCode === 200) { return JSON.parse(response.body); } console.error(`Request failed: ${response.statusCode}`); return null; } scrapePage(pageUrl).then((data) => { if (data) console.log(JSON.stringify(data.body, null, 2)); });
Ответ скрейпера содержит поля уровня страницы, такие как название страницы и текст описания, вместе с массивом публичных постов, опубликованных страницей, где каждый пост включает текст и публичные счётчики реакций, комментариев и репостов. Поскольку скрейпер берёт на себя парсинг, вам не нужно гоняться за CSS-селекторами против разметки, меняющейся еженедельно. С Crawling API поставляется несколько скрейперов; скрейпер facebook-page создан специально для макетов публичных страниц.
Шаг 3: извлеките только публичные поля уровня страницы
Теперь сузьте вывод скрейпера точно до нужных публичных полей и отбросьте всё остальное. Здесь мы применяем ограничение области: название страницы, текст поста и три агрегированных счётчика на пост. Мы не читаем и не храним идентичности комментаторов или тексты отдельных комментариев.
const { CrawlingAPI } = require('crawlbase'); const api = new CrawlingAPI({ token: 'YOUR_CRAWLBASE_TOKEN' }); const pageUrl = 'https://www.facebook.com/Alibaba.comGlobal/'; async function scrapePage(url) { const options = { ajax_wait: 'true', scraper: 'facebook-page' }; const response = await api.get(url, options); if (response.statusCode !== 200) { console.error(`Request failed: ${response.statusCode}`); return null; } return JSON.parse(response.body).body; } function extractPublicData(page) { const posts = (page.posts || []).map((post) => ({ text: post.text || null, reactionCount: post.reactionCounts || 0, commentCount: post.commentsCount || 0, shareCount: post.sharesCount || 0, })); return { pageName: page.pageName || page.title || null, postCount: posts.length, posts, }; } async function main() { const page = await scrapePage(pageUrl); if (!page) return; const publicData = extractPublicData(page); console.log(JSON.stringify(publicData, null, 2)); } main();
Функция extractPublicData выполняет ограничивающую работу. Она сохраняет название страницы, текст поста и три публичных счётчика на пост, не читая ничего, привязанного к идентифицируемому человеку. Каждое поле имеет безопасное значение по умолчанию, если скрейпер его опускает, поскольку не каждый пост показывает репосты или комментарии. Имена полей соответствуют ключам ответа скрейпера (pageName, reactionCounts, commentsCount, sharesCount); если ключ возвращает пустое значение, проверьте живой вывод скрейпера и адаптируйте, макеты страниц эволюционируют.
Как выглядит вывод
Запустите полный скрипт командой node script.js и получите компактный JSON-объект: название страницы и список публичных постов с их текстом и агрегированными счётчиками, готовый для записи в файл или базу данных.
{ "pageName": "Alibaba.com", "postCount": 2, "posts": [ { "text": "Source smarter this season with verified suppliers.", "reactionCount": 1280, "commentCount": 94, "shareCount": 37 }, { "text": "New buyer guide: how to vet a manufacturer in 5 steps.", "reactionCount": 863, "commentCount": 51, "shareCount": 22 } ] }
Каждое значение здесь является публичным и уровня страницы. Нет имён пользователей, нет текстов отдельных комментариев, нет данных профилей, это именно та граница, которую выдерживает этот туториал.
Обработка прокрутки и AJAX-контента
Два параметра из шага 1 делают Facebook управляемым, и они заслуживают понимания перед тем, как запускать это в каком-либо объёме.
-
ajax_wait. Facebook гидрирует контент через AJAX после загрузки документа. Без
ajax_wait: 'true'вы захватываете страницу до поступления этого контента и получаете разметку загрузчика. С ним API возвращает HTML только после разрешения асинхронных вызовов. -
scroll и scroll_interval. Посты загружаются постепенно по мере прокрутки пользователем.
scroll: 'true'симулирует это, аscroll_intervalконтролирует, сколько секунд прокручивать, до максимума в 60. Более длинный интервал показывает больше постов за счёт более медленного запроса, поэтому настройте его под фактическое количество нужных недавних постов.
Помимо данных, Crawling API может также возвращать скриншот отрендеренной страницы с параметром screenshot, передавая в ответе screenshot_url со сроком действия около часа. Это полезно для визуального подтверждения захваченного, но именно структурированные поля выше являются тем, на чём строите.
Соблюдение ограничений скорости
Даже при обработанном рендеринге Facebook применяет строгие ограничения скорости, и их превышение грозит временной или постоянной блокировкой. Несколько привычек сохраняют запуск здоровым и уважительным.
- Регулируйте запросы. Не бомбардируйте страницы в плотном цикле. Разбивайте запросы и держите общий объём низким; это одновременно проявление уважения и самый быстрый способ избежать пометки.
- Полагайтесь на ротацию. Запросы, распределённые по пулу резидентных IP, значительно менее вероятно превысят лимит, чем один датацентровый адрес. Crawling API берёт на себя ротацию; если строите собственный стек, именно в эту часть стоит инвестировать. Более широкое руководство см. в статье как скрейпить сайты без блокировок.
- Следите за кодами статусов. Когда ответы начинают возвращаться как проверки или ошибки, это сигнал к отступлению, а не шум для преодоления.
Для более крупных, плановых задач по многим публичным страницам асинхронная очередь подходит лучше, чем синхронный цикл. Наше руководство о том, как извлекать данные с помощью Crawlbase Crawler, охватывает этот паттерн, при котором запросы ставятся в очередь и доставляются на вебхук вместо блокировки скрипта.
Законно ли скрейпить Facebook?
Прочитайте этот раздел перед запуском чего-либо. Условия использования Facebook строго ограничивают автоматизированный сбор данных. Его условия и политики автоматизированного доступа запрещают скрейпинг в широких формулировках, и это ограничение действует независимо от аккуратности инструментов. Ни один код в этом руководстве не отменяет условия Facebook; он лишь делает техническую часть рабочей. Прежде чем что-либо собирать, прочитайте Условия использования Facebook, его robots.txt, а также политики разработчика и платформы и воспринимайте все три как границу того, к чему можно прикасаться.
Если вы продолжаете в исследовательских или образовательных целях, строго держитесь узкой публичной полосы. Собирайте только публичные данные с публичных бизнес-страниц или страниц брендов: название страницы, текст постов, опубликованных самой страницей, и агрегированные публичные счётчики вовлечённости. Не собирайте персональные данные. Это означает отсутствие личных профилей, закрытых групп, списков подписчиков или участников, личных сообщений и отдельных комментариев, привязанных к идентифицируемым людям. Имена пользователей, хэндлы, данные профилей и написанные пользователями комментарии являются персональными данными, и создание профиля идентифицируемого человека из них, именно то, чего следует избегать. Агрегируйте на уровне страницы и поста, как делает код выше, и останавливайтесь там.
Там, где персональные данные вообще задействованы, применяется законодательство о конфиденциальности. В соответствии с GDPR и CCPA вам нужно законное основание для обработки персональных данных и необходимо соблюдать запросы на удаление и отказ, что является серьёзным обязательством, которого агрегированные счётчики публичных страниц специально позволяют избежать. Для любого производственного использования санкционированный и значительно более безопасный путь, официальный Facebook Graph API, предоставляющий авторизованный, ограниченный по скорости доступ к данным, которые владелец страницы или приложение имеет право видеть, с чёткими условиями. Настоятельно предпочитайте Graph API. Используйте подход с публичными данными из этого руководства только для небольшой, образовательной работы с публичными страницами и никогда как способ обойти логин, настройку конфиденциальности или условия платформы.
Ключевые выводы
- Facebook рендерится на стороне клиента. Простой запрос возвращает разметку загрузчика, поэтому необходимо отрендерить страницу, дождаться AJAX и симулировать прокрутку, прежде чем появится какой-либо контент.
-
Рендеринг и доверенный IP в одном вызове. Crawling API с JS-токеном делает оба;
ajax_wait,scrollиscroll_intervalконтролируют способ захвата страницы. - Используйте встроенный скрейпер facebook-page. Он возвращает публичные данные страницы как JSON, избавляя от необходимости поддерживать селекторы против постоянно меняющейся разметки.
- Ограничьте область публичными данными уровня страницы. Только название страницы, текст поста и агрегированные счётчики реакций, комментариев и репостов; никогда не идентичности комментаторов, профили, закрытые группы или отдельные комментарии.
- Предпочитайте официальный API. Условия Facebook строго ограничивают скрейпинг, а GDPR/CCPA применяются к персональным данным, поэтому Facebook Graph API является санкционированным путём для всего, кроме небольшого образовательного использования.
Часто задаваемые вопросы
Почему простой запрос не возвращает реальный контент со страницы Facebook?
Потому что Facebook загружает контент на стороне клиента. Название страницы, раздел «О себе» и посты поступают через JavaScript и AJAX после исходного документа, а дополнительные посты появляются только при прокрутке. Голый HTTP-запрос захватывает страницу до того, как это происходит, поэтому вы получаете разметку загрузчика вместо данных. Рендеринг страницы и ожидание AJAX с JS-токеном Crawling API, это то, что возвращает реальный контент.
Нужен ли обычный токен или JS-токен для Facebook?
Используйте JavaScript (JS) токен. Facebook строит страницы с клиентским рендерингом, поэтому обычный токен, загружающий статичный HTML, возвращает разметку загрузчика без значимого контента. JS-токен сначала рендерит страницу в реальном браузере, что и делает данные видимыми.
Какие публичные данные можно безопасно извлечь с бизнес-страницы Facebook?
Придерживайтесь публичных полей уровня страницы: название страницы, текст постов, опубликованных самой страницей, и агрегированные счётчики вовлечённости (реакции, комментарии, репосты) как числа. Избегайте всего личного: имён комментаторов, текстов отдельных комментариев, данных профилей, списков подписчиков, закрытых групп и всего за логином. Агрегированные счётчики на уровне страницы и поста, это защищаемая область.
Можно ли скрейпить личные профили или закрытые группы?
Нет, и это руководство не охватывает их. Личные профили, закрытые группы, списки участников и личные сообщения являются персональными и непубличными данными, а их сбор противоречит условиям Facebook и законодательству о конфиденциальности. Это руководство намеренно ограничено публичными бизнес-страницами и страницами брендов. Для санкционированного доступа к большему используйте Facebook Graph API с надлежащей авторизацией.
Стоит ли вместо этого использовать Facebook Graph API?
Для любого производственного или коммерческого использования, да. Facebook Graph API является официальным, авторизованным путём с ограничениями скорости и чёткими условиями, и это правильный инструмент, когда владелец страницы или приложение нуждается в надёжном доступе. Подход скрейпинга публичных данных здесь подходит только для небольшой, образовательной работы с публичными страницами, где нет доступа к API, и он всё равно должен уважать условия Facebook.
Как избежать блокировки или ограничения скорости?
Держите объём запросов низким, разбивайте запросы вместо плотного цикла и маршрутизируйте через ротируемые резидентные IP, чтобы ни один адрес не превысил лимиты Facebook. Crawling API управляет ротацией и доверенным пулом IP за вас. Следите за кодами статусов и отступайте при первых признаках проверок или ошибок, а не преодолевайте их.
Обходите любой сайт в масштабе, без борьбы с инфраструктурой.
Crawlbase берёт на себя прокси, отпечатки и CAPTCHA, чтобы ваша команда выпускала конвейеры данных вместо поддержки обвязки краулинга. 1 000 запросов бесплатно, без карты.
