Парсинг веб-страниц с помощью Puppeteer
Сбор данных, мониторинг контента, автоматизированные задачи и т. д. часто требуют парсинга данных с веб-сайтов. Существует множество фреймворков для парсинга данных с веб-страниц. Некоторые из них - это Axios, Puppeteer, Cheerio, JSDOM и т. д., но Cheerio
и Puppeteer
являются популярными фреймворками для парсинга веб-страниц на JavaScript благодаря своим гибким API и легкости использования.
В этой статье мы рассмотрим фреймворк Puppeteer и причины его использования. Мы рассмотрим установку, основную структуру Puppeteer, способы перехода на веб-сайт и извлечения данных, а также в конце - как взаимодействовать с динамическими страницами, такими как нажатие кнопок и прокрутка.
Что такое Puppeteer и почему он полезен?
Puppeteer - это библиотека Node.js
. Он предоставляет простой в использовании API для тестирования веб-приложений, извлечения данных с веб-страниц, автоматизации задач, взаимодействия с динамическими веб-страницами и т. д.
Puppeteer является подходящим выбором для парсинга веб-страниц, потому что:
- Поддержка и интуитивный API: Он имеет API, который очень полезен для извлечения данных с веб-страниц и также ценен для автоматизации большинства задач, связанных с вебом.
- Безголовый режим просмотра: Вы можете извлекать данные с веб-сайта, не открывая его. Он будет извлекать все данные внутренне, что делает его более быстрым и эффективным для парсинга веб-страниц.
- Поддержка современных веб-технологий: Puppeteer поддерживает популярные веб-технологии, такие как WebSockets и IndexedDB. Пользователь может взаимодействовать с сайтом, нажимая кнопки, прокручивая веб-страницы и т. д.
Инициализация Puppeteer
Создайте новую директорию с любым именем (например, puppeteer_scraping).
mkdir puppeteer_scraping
Создайте папку, которая будет содержать файлы JavaScript. Затем перейдите в эту папку и выполните следующую команду, чтобы инициализировать файл package.json
.
npm init -y
Последний шаг - установка Puppeteer с помощью команды npm install
.
npm install puppeteer
Подождите, прежде чем продолжить дальше, перейдите в package.json
и добавьте "type":"module"
, чтобы обрабатывать функции ES6, такие как шаблонные литералы, классы, промисы и т. д.
{
"name": "puppeteer_scraping",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"puppeteer": "^19.6.3"
},
"type": "module"
}
Сессионная повторная запись для разработчиков
Раскройте фрустрации, поймите ошибки и исправьте замедления, как никогда раньше с помощью OpenReplay - набора инструментов для сессионной повторной записи с открытым исходным кодом для разработчиков. Он может быть развернут на собственном сервере в течение нескольких минут, предоставляя полный контроль над данными ваших клиентов.
_Счастливого отладки! _Попробуйте использовать OpenReplay сегодня.
Извлечение данных с веб-страниц
Мы можем использовать либо Wikipedia, либо веб-сайт Toscrap, чтобы понять парсинг веб-страниц. Но в этой статье мы будем работать с сайтом Toscrap. Для начинающих или для начала работы с парсингом веб-страниц, веб-сайт Toscrap очень полезен и прост в использовании.
Сайт Toscrap - это песочница для парсинга веб-страниц, содержащая два основных проекта, разработанных специально для парсинга веб-страниц. Мы будем парсить данные только с Quotes to Scrap.
Инициализация скрипта:
Создайте новый файл с именем index.js
. В скрипте определена функция с именем parseQuotes()
, которая будет обрабатывать процесс парсинга.
В функции parseQuotes()
запускается новый экземпляр браузера с помощью puppeteer.launch()
. Режим Headless
установлен в значение false
, чтобы вы могли видеть веб-страницы в браузере.
Затем используйте browser.newPage()
для создания новой страницы в браузере и передайте URL веб-страницы в функцию page.goto()
для перехода по нему.
Сейчас мы не закрываем браузер, но в конце функции мы должны вызвать метод browser.close()
, чтобы закрыть его.
// Импортируем модуль Puppeteer
import puppeteer from "puppeteer";
// Определяем функцию для обработки парсинга данных
const parseQuotes = async () => {
// Запускаем новый экземпляр браузера
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
});
// Открываем новую страницу в браузере
const page = await browser.newPage();
// Переходим по URL
await page.goto("http://quotes.toscrape.com/");
};
// Вызываем функцию
parseQuotes();
После запуска вышеуказанного скрипта с помощью node index.js
откроется новая страница в браузере. Вы можете увидеть изображение, приведенное ниже:
Получение первой цитаты
Парсинг веб-страниц требует работы с HTML DOM. Когда веб-страница загружается, браузер создает Document Object Model этой веб-страницы.
Правильный способ начать парсинг текста - это изучить веб-страницу, перемещаться по ней и извлекать нужный текст. На изображении ниже видно, что внутри класса quote (class="quote"
) написаны классы text, author и tags.
На изображении ниже показано увеличенное изображение предыдущего изображения. Вы можете видеть, как классы, такие как text, author и tags, написаны внутри контейнера <div>
. Внутри контейнера есть классы, такие как text (class="text"
), author (class="author"
) и tags (class="tags"
).
Давайте посмотрим на код для парсинга нашей первой цитаты. В приведенном ниже коде функция page.evaluate()
будет выполнять код в контексте загруженной страницы. Затем мы будем использовать querySelector()
для выбора элемента на веб-странице на основе класса .quote.
После этого мы можем извлечь текст и автора, передав .text
и .author
внутри функции querySelector()
.
Затем отобразите весь текст и имя автора, а затем закройте экземпляр браузера.
// Импортирование модуля Puppeteer
import puppeteer from "puppeteer";
// Определение функции для обработки парсинга данных
const scrapQuotes = async () => {
// Запуск нового экземпляра браузера
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
});
// Открытие новой страницы в браузере
const page = await browser.newPage();
// Переход по URL-адресу
await page.goto("http://quotes.toscrape.com/");
// Получение данных со страницы
const quotes = await page.evaluate(() => {
// Использование querySelector для выбора элемента на веб-странице на основе его CSS-селектора
const quote = document.querySelector(".quote");
// Извлечение текста
const text = quote.querySelector(".text").innerText;
// Извлечение автора
const author = quote.querySelector(".author").innerText;
return { text, author };
});
// Вывод цитат
console.log(quotes);
// Закрытие экземпляра браузера
await browser.close();
};
// Вызов функции
scrapQuotes();
Результат:
{
text: '“Мир, который мы создали, является процессом нашей мысли. Его нельзя изменить, не изменив нашего мышления.”',
author: 'Альберт Эйнштейн'
}
Как видно из приведенного выше результата, мы получили первую цитату с веб-сайта с именем автора.
Получение всех цитат на веб-странице
Для получения всех цитат на текущей странице вам понадобится использовать функцию querySelectorAll()
вместо querySelector()
.
На изображении ниже вы можете увидеть десять цитат на текущей странице.
Передайте имя класса (quote
) внутри функции querySelectorAll()
для извлечения всех цитат.
Эта функция вернет NodeList элементов, затем вам нужно преобразовать его в массив элементов.
В конечном итоге вы можете перебрать этот массив цитат и получить всю информацию, такую как текст и автор.
// Импортируйте модуль Puppeteer
import puppeteer from "puppeteer";
// Определите функцию для обработки парсинга данных
const scrapQuotes = async () => {
// Запуск нового экземпляра браузера
const browser = await puppeteer.launch({
headless: false,
defaultViewport: null,
});
// Откройте новую страницу в браузере
const page = await browser.newPage();
// Перейдите по URL-адресу
await page.goto("http://quotes.toscrape.com/");
// Получите данные страницы
const quotes = await page.evaluate(() => {
// Получение всех элементов с классом .quote
const quotesArray = document.querySelectorAll(".quote");
// Преобразование NodeList цитат в массив и
// использование map для извлечения текста и автора каждой цитаты
return Array.from(quotesArray).map((quote) => {
const text = quote.querySelector(".text").innerText;
const author = quote.querySelector(".author").innerText;
return { text, author };
});
});
// Вывод цитат
console.log(quotes);
// Закрытие экземпляра браузера
await browser.close();
};
// Вызов функции
scrapQuotes();
Перейти на следующую страницу:
Метод click() может быть использован для нажатия на кнопку. Следующая кнопка находится внутри ul > li > a
следующего изображения.
В методе click() необходимо передать .next > a
, потому что <a>
находится внутри класса next, который также находится внутри класса pager. Вы также можете передать .pager > .next > a
для большей надежности. Функция browser.close()
закомментирована в коде, чтобы следующая страница отобразилась. Если вы раскомментируете ее, страница закроется мгновенно, и вы не сможете ее увидеть.
// Вывести цитаты
console.log(quotes);
// Нажать на кнопку "Следующая"
const searchResult = ".next > a";
await page.waitForSelector(searchResult);
await page.click(searchResult);
// Закрыть экземпляр браузера
// await browser.close();
Результат:
Совет: Вы можете сделать гораздо больше с парсингом веб-страниц. Вы можете спарсить некоторые интернет-магазины, чтобы получить цены на товары, рейтинги и т.д.
В нашем случае вы можете провести еще множество экспериментов, таких как получение всех тегов и удаление дубликатов. Вы можете перемещаться между страницами, используя кнопки Следующая и Предыдущая, и нажатие на ссылку about предоставит вам некоторую биографическую информацию об авторе.
Заключение
В этой статье мы рассмотрели, как парсить веб-страницы с помощью Puppeteer. Мы изучили основы Puppeteer, как переходить на веб-сайт и извлекать информацию, взаимодействовать с динамическими веб-страницами и т. д.
Puppeteer является популярным инструментом для парсинга веб-страниц, поскольку он предлагает простой и эффективный способ извлечения данных с веб-сайтов. Puppeteer отлично подходит для проектов по парсингу веб-страниц благодаря своей возможности запуска браузера в безголовом режиме и простому и интуитивно понятному API.