Початок роботи з веб-скрапінгом у JavaScript

Веб-скрейпінг – це захоплива галузь у світі програмування, яка відкриває безліч можливостей.

Що ж таке веб-скрейпінг і чому він набув такої популярності?

Давайте разом розглянемо ці питання.

Що являє собою веб-скрейпінг?

Веб-скрейпінг, або веб-збирання – це автоматизований процес видобування даних з веб-сайтів.

Сфери застосування веб-скрейпінгу є надзвичайно різноманітними. Наприклад, можна отримувати ціни на товари та порівнювати їх на різних онлайн-платформах, відстежувати щоденні ціни з різних веб-джерел, або навіть створити власну пошукову систему, аналогічну Google чи Yahoo. Перелік можливостей можна продовжувати.

Веб-скрейпінг надає набагато більше можливостей, ніж може здатися на перший погляд. Опанувавши методи видобування інформації з веб-ресурсів, ви зможете використовувати її для різних цілей.

Програма, яка витягує дані з веб-сайтів, називається веб-скрепером. Ми навчимося створювати такі скрепери, використовуючи JavaScript.

Процес веб-скрейпінгу складається з двох ключових етапів:

  • Отримання вихідних даних з веб-сайту за допомогою бібліотек запитів та безголового браузера.
  • Розбір та аналіз отриманих даних з метою вилучення конкретної потрібної інформації.

Без зайвих зволікань, перейдемо до практики.

Налаштування середовища розробки

Передбачається, що у вас вже встановлено Node.js. Якщо ж ні, то вам необхідно ознайомитися з інструкцією по встановленню NodeJS.

Для веб-скрейпінгу на JavaScript ми будемо використовувати пакети node-fetch та cheerio. Щоб використовувати сторонні пакети, необхідно налаштувати проект за допомогою npm.

Розглянемо кроки, необхідні для налаштування проекту:

  • Створіть папку з назвою web_scraping та перейдіть до неї.
  • Виконайте команду npm init для ініціалізації проекту.
  • Відповідайте на запитання згідно з вашими вподобаннями.
  • Встановіть необхідні пакети за допомогою команди:
npm install node-fetch cheerio

Давайте коротко розглянемо функціонал встановлених пакетів.

node-fetch

Пакет node-fetch переносить функціонал window.fetch у середовище Node.js. Це дозволяє робити HTTP-запити та отримувати вихідні дані з веб-сайтів.

cheerio

Пакет cheerio використовується для розбору та вилучення потрібної інформації з вихідних даних.

Двох пакетів node-fetch та cheerio достатньо для веб-скрейпінгу на JavaScript. В рамках даного посібника ми не будемо розглядати усі методи, які пропонують ці пакети. Ми зосередимось на основному алгоритмі веб-скрейпінгу та найбільш корисних методах, які використовуються в цьому процесі.

Таким чином, ви зможете отримати практичні навички веб-скрейпінгу. Тож, перейдемо до роботи.

Видобування списку переможців Кубка світу з крикету

У цьому розділі ми безпосередньо займемося веб-скрейпінгом.

Які дані ми будемо видобувати?

З назви розділу неважко здогадатися. Так, ми видобудемо список усіх переможців та фіналістів Кубка світу з крикету.

  • Створіть у вашому проекті файл з назвою extract_cricket_world_cups_list.js.
  • Ми будемо використовувати сторінку Кубка світу з крикету у Вікіпедії як джерело необхідної інформації.
  • Спочатку отримаємо вихідні дані, використовуючи пакет node-fetch.
  • Наведений нижче код отримує вихідні дані з вищезгаданої сторінки Вікіпедії.
const fetch = require("node-fetch");

// Функція для отримання вихідних даних
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL-адреса для отримання даних
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// Початок програми
const getCricketWorldCupsList = async () => {
   const cricketWorldCupRawData = await getRawData(URL);
   console.log(cricketWorldCupRawData);
};

// Виклик основної функції
getCricketWorldCupsList();

Ми отримали вихідні дані з URL-адреси. Тепер необхідно витягнути потрібну нам інформацію з цих даних. Скористаємося пакетом cheerio для аналізу даних.

Отримання даних, які включають HTML-теги, за допомогою cheerio є досить простим. Перш ніж приступити до вилучення реальних даних, давайте розглянемо простий приклад аналізу даних за допомогою cheerio.

  • Виконаємо аналіз HTML-коду за допомогою методу cheerio.load.
const parsedSampleData = cheerio.load(
      `<div id="container"><p id="title">I'm title</p></div>`
   );
  • Ми проаналізували наведений вище HTML-код. Як тепер витягнути вміст тегу p? Це аналогічно селекторам в DOM JavaScript.

console.log(parsedSampleData("#title").text());

Ви можете вибирати теги, як вам потрібно. Більше інформації про різні методи можна знайти на офіційному сайті cheerio.

  • Тепер настав час видобути список переможців Кубка світу. Щоб отримати потрібну інформацію, необхідно знати HTML-теги, які містять цю інформацію на сторінці. Перейдіть на сторінку Кубка світу з крикету у Вікіпедії та перевірте структуру сторінки, щоб знайти потрібні HTML-теги.

Ось повний код:

const fetch = require("node-fetch");
const cheerio = require("cheerio");

// Функція для отримання вихідних даних
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL-адреса для отримання даних
const URL = "https://en.wikipedia.org/wiki/Cricket_World_Cup";

// Початок програми
const getCricketWorldCupsList = async () => {
   const cricketWorldCupRawData = await getRawData(URL);

   // Розбір даних
   const parsedCricketWorldCupData = cheerio.load(cricketWorldCupRawData);

   // Видобування даних з таблиці
   const worldCupsDataTable = parsedCricketWorldCupData("table.wikitable")[0]
      .children[1].children;

   console.log("Рік --- Переможець --- Фіналіст");
   worldCupsDataTable.forEach((row) => {
      // Видобування тегів `td`
      if (row.name === "tr") {
         let year = null,
            winner = null,
            runner = null;

         const columns = row.children.filter((column) => column.name === "td");

         // Видобування року
         const yearColumn = columns[0];
         if (yearColumn) {
            year = yearColumn.children[0];
            if (year) {
               year = year.children[0].data;
            }
         }

         // Видобування переможця
         const winnerColumn = columns[3];
         if (winnerColumn) {
            winner = winnerColumn.children[1];
            if (winner) {
               winner = winner.children[0].data;
            }
         }

         // Видобування фіналіста
         const runnerColumn = columns[5];
         if (runnerColumn) {
            runner = runnerColumn.children[1];
            if (runner) {
               runner = runner.children[0].data;
            }
         }

         if (year && winner && runner) {
            console.log(`${year} --- ${winner} --- ${runner}`);
         }
      }
   });
};

// Виклик основної функції
getCricketWorldCupsList();

І ось видобуті дані:

Рік --- Переможець --- Фіналіст
1975 --- West Indies --- Australia
1979 --- West Indies --- England
1983 --- India --- West Indies
1987 --- Australia --- England
1992 --- Pakistan --- England
1996 --- Sri Lanka --- Australia
1999 --- Australia --- Pakistan
2003 --- Australia --- India
2007 --- Australia --- Sri Lanka
2011 --- India --- Sri Lanka
2015 --- Australia --- New Zealand
2019 --- England --- New Zealand

Чудово 😎, правда?

Шаблон веб-скрепера

Отримання вихідних даних з URL-адреси є стандартним процесом у кожному проекті веб-скрейпінгу. Єдиною частиною, яка змінюється, є видобування даних згідно з конкретними вимогами. Ви можете використовувати наведений нижче код як шаблон для ваших проектів:

const fetch = require("node-fetch");
const cheerio = require("cheerio");
const fs = require("fs");

// Функція для отримання вихідних даних
const getRawData = (URL) => {
   return fetch(URL)
      .then((response) => response.text())
      .then((data) => {
         return data;
      });
};

// URL-адреса для отримання даних
const URL = "https://example.com/";

// Початок програми
const scrapeData = async () => {
   const rawData = await getRawData(URL);
   // Розбір даних
   const parsedData = cheerio.load(rawData);
   console.log(parsedData);
   // Пишіть код для видобування даних тут
   // ...
   // ...
};

// Виклик основної функції
scrapeData();

Висновок

Ви навчилися видобувати дані з веб-сторінок. Тепер ваша черга практикуватися.

Я також рекомендую ознайомитися з популярними фреймворками для веб-скрейпінгу та хмарними рішеннями для цієї галузі.

Вдалого кодування 🙂

Чи сподобалась вам стаття? Поділіться нею з іншими!