Веб-скрапинг, веб-сбор или извлечение веб-данных — это парсинг данных, используемый для извлечения данных с веб-сайтов. Это может быть полезно, когда ресурс не предоставляет общедоступный 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 для интерактивной документации.