Веб-краулер на основе JSDOM
В этом примере показано, как использовать JSDOMCrawler
для взаимодействия с веб-сайтами с помощью DOM-реализации jsdom.
В данном скрипте мы откроем калькулятор из примеров React, нажмем кнопки 1
+
1
=
и получим результат.
Run on
import { JSDOMCrawler, log } from 'crawlee';
// Создаем экземпляр класса JSDOMCrawler - краулер, который автоматически
// загружает URL и парсит их HTML с помощью библиотеки jsdom.
const crawler = new JSDOMCrawler({
// Установка опции `runScripts` в `true` позволяет краулеру выполнять клиентский JavaScript код на странице.
// Это требуется для некоторых веб-сайтов (например, в этом примере), но может представлять угрозу безопасности.
runScripts: true,
// Эта функция будет вызываться для каждого крауленного URL.
// Здесь мы извлекаем объект окна из опций и используем его для извлечения данных из страницы.
requestHandler: async ({ window }) => {
const { document } = window;
// Объект `document` аналогичен объекту `window.document`, который вы знаете из ваших любимых браузеров.
// Благодаря этому, вы можете использовать обычные браузерные API здесь.
document.querySelectorAll('button')[12].click(); // 1
document.querySelectorAll('button')[15].click(); // +
document.querySelectorAll('button')[12].click(); // 1
document.querySelectorAll('button')[18].click(); // =
const result = document.querySelectorAll('.component-display')[0].childNodes[0] as Element;
// Результат передается в консоль. В отличие от краулеров Playwright или Puppeteer,
// этот вызов консоли идет в Node.js, а не в браузерную консоль. Весь код здесь выполняется в Node.js!
log.info(result.innerHTML); // 2
},
});
// Запускаем краулер и ждем, пока он закончит работу.
await crawler.run(['https://ahfarmer.github.io/calculator/']);
log.debug('Краулер закончил работу.');
В следующем примере мы используем JSDOMCrawler
для обхода списка URL-адресов из внешнего файла. Каждый URL загружается с помощью простого HTTP-запроса, затем HTML парсится с использованием DOM-реализации jsdom для извлечения данных: заголовка страницы и всех тегов h1
.
Run on
import { JSDOMCrawler, log, LogLevel } from 'crawlee';
// Краулеры имеют различные утилиты, например, для логирования.
// Здесь мы используем уровень логирования `DEBUG` для улучшения отладочного опыта.
// Эта функциональность является необязательной!
log.setLevel(LogLevel.DEBUG);
// Создаем экземпляр класса JSDOMCrawler - краулера, который автоматически загружает URL и парсит их HTML с использованием библиотеки jsdom.
const crawler = new JSDOMCrawler({
// Краулер загружает и обрабатывает веб-страницы параллельно, с автоматическим управлением конкоррентностью
// на основе доступной системной памяти и ЦП (см. класс AutoscaledPool).
// Здесь мы определяем некоторые жесткие ограничения для конкоррентности.
minConcurrency: 10,
maxConcurrency: 50,
// При ошибке повторите каждую страницу не более одного раза.
maxRequestRetries: 1,
// Увеличьте таймаут для обработки каждой страницы.
requestHandlerTimeoutSecs: 30,
// Ограничьте 10 запросов на один краулинг
maxRequestsPerCrawl: 10,
// Эта функция будет вызываться для каждого URL для краулинга.
// Она принимает один параметр, который является объектом с опциями:
// https://crawlee.dev/api/jsdom-crawler/interface/JSDOMCrawlerOptions#requestHandler
// Мы используем для демонстрации только 2 из них:
// - request: экземпляр класса Request с информацией, такой как URL, который краулится, и HTTP-метод
// - window: объект JSDOM window
async requestHandler({ pushData, request, window }) {
log.debug(`Processing ${request.url}...`);
// Извлеките данные из страницы
const title = window.document.title;
const h1texts: { text: string }[] = [];
window.document.querySelectorAll('h1').forEach((element) => {
h1texts.push({
text: element.textContent!,
});
});
// Сохраните результаты в набор данных. В локальной конфигурации
// данные будут сохранены как JSON-файлы в ./storage/datasets/default
await pushData({
url: request.url,
title,
h1texts,
});
},
// Эта функция вызывается, если обработка страницы завершилась неудачно более maxRequestRetries + 1 раз.
failedRequestHandler({ request }) {
log.debug(`Запрос ${request.url} не выполнен дважды.`);
},
});
// Запустите краулер и дождитесь его завершения.
await crawler.run(['https://crawlee.dev']);
log.debug('Краулер закончил работу.');