Веб-скрапинг, веб-сбор или извлечение веб-данных — это парсинг данных, используемый для извлечения данных с веб-сайтов. Это может быть полезно, когда ресурс не предоставляет общедоступный API для своих данных или когда ваше приложение переносит содержимое одного ресурса на себя.
Скрапинг можно выполнять с помощью различных программ. При желании можно выполнять веб-скрапинг с помощью чистого Node, но есть библиотеки, которые упрощают этот процесс.
Puppeteer — это библиотека Node, которая предоставляет высокоуровневый API для управления Chrome или Chromium через «DevTools Protocol. Puppeteer по умолчанию работает безголовым, но его можно настроить для работы с полным (не безголовым) Chrome или Chromium». — из репозитория Puppeteer на github README.
Puppeteer запускает безголовый браузер, который вы можете использовать (среди прочего) для очистки веб-страницы на предмет ее содержимого с помощью селекторов HTML DOM. В этой статье мы покажем некоторые основы Puppeteer, которые вы можете использовать для разработки парсеров или автоматизации тестирования пользовательского интерфейса для вашего приложения.
Давайте создадим простой одностраничный парсер с помощью puppeteer. Очистка общедоступных данных обычно разрешена, но иногда очистка может быть запрещена политикой конфиденциальности. По этой причине мы будем очищать веб-сайт со списком котировок, предоставленный toscrape.com, веб-сайт, созданный для сбора.
Начните с установки библиотеки puppeteer в свой проект. Следующая команда установит как библиотеку, так и автономный браузер, для которого предназначен API:
npm i puppeteer # or "yarn add puppeteer"
Нам нужно инициализировать безголовый браузер, лучше сделать это в отдельном файле, который мы назовем «browser.js», чтобы структура файла была хорошо организована, так как ваш парсер может очень быстро усложняться.
const puppeteer = require('puppeteer'); //import puppeteer async function startBrowser(){ let browser; try { console.log("Opening the browser......"); browser = await puppeteer.launch({ headless: true, });
//Start browser instance in headless mode. } catch (err) { console.log("Could not create a browser instance => : ", err); } return browser; }
module.exports = {startBrowser}
Обратите внимание, что функция startBrowser() является асинхронной и используется обработчик ожидания. Это связано с тем, что метод launch() в puppeteer возвращает обещание, которое необходимо разрешить. Это то, что применимо к большинству API puppeteer.
Затем мы можем создать новый файл с именем «pageScraper.js», в котором будет определена фактическая функциональность парсера.
const scraperObject = { url: 'https://quotes.toscrape.com/', async scraper(browserInstance){ let browser = await browserInstance; //init browser let page = await browser.newPage(); //init page console.log(`Navigating to ${this.url}...`); // Navigate to the selected page await page.goto(this.url); //nav to url. // Wait for the required DOM to be rendered await page.waitForSelector('body > div > div:nth-child(2) > div.col-md-8'); //Use DOM selectors to find the quote text and author of each quote listed on the page. let quoteList = await page.$$eval('body > div > div:nth-child(2) > div.col-md-8 > div', quotes => { let data = [] //init array containing quote objects text = quotes.map(el => el.querySelector('div > span:nth-child(1).text').textContent); author = quotes.map(el => el.querySelector('div > span:nth-child(2) > small').textContent) //Create the quotes object for (let i = 0; i < quotes.length; i++) { data[i] = { text: text[i], author: author[i] } } return data; //Return promise }) return quoteList; } } module.exports = scraperObject;
Скребок сделан. Осталось только создать индексный файл, в котором мы будем передавать экземпляр браузера нашему парсеру. Давайте создадим index.js.
const browserObject = require('./browser'); const pageScraper = require('./pageScraper'); //Start the browser and create a browser instance let browserInstance = browserObject.startBrowser(); // Pass the browser instance to the scraper object pageScraper.scraper(browserInstance)
Вот и все! Теперь мы можем запустить наш парсер через узел с помощью команды:
node index.js
Это чрезвычайно простой пример. Он может очищать только одностраничные приложения, однако это может быть хорошей базовой структурой для создания более сложных парсеров.
Puppeteer API поставляется с действительно подробной документацией, которую можно найти на их github или на pptr.dev для интерактивной документации.