Парсер на JavaScript и Node.js

14.09.21 в 08:35 Interesting 1286

Другим преимуществом, ускоряющим процесс разработки, является поддержка npm (Node.js package manager) - менеджер пакетов, открывающий доступ к огромной базе дополнительных библиотек, что упрощает процесс разработки, в том числе запуск скрейпинг-ботов.

Начать работу с Node.js довольно просто. Он специально разработан с целью облегчить и ускорить начинающим разработчикам процесс освоения этой технологии. В конечно итоге для начала изучения достаточно иметь базовые знания JavaScript.

В этой статье содержится руководство по созданию простого проекта на Node.js, позволяющего в автоматическом режиме собирать интересующую информацию с целевого ресурса.

Создание проекта и установка зависимостей

Настройка среды разработки

Для начала работы необходимо установить сам node.js. Ссылки на руководства по установке для всех популярных ОС и актуальные версии фреймворка можно найти на официальном сайте. Проверить правильность установки можно запросом версии node.js и npm из терминала:

$ node -v
v14.15.5
$ npm -v
6.14.11

Дополнительно можно подготовить удобный для вас текстовый редактор для работы с кодом. Подойдет любой, даже стандартный для вашей ОС редактор. Однако, для удобства лучше использовать один из популярных редакторов кода, например: VS Code, Sublime text, Atom или WebStorm.

Инициализация проекта

Перед тем как создать проект выберите или создайте папку, в которой будут хранится все данные необходимые для успешной работы скрейпинг-бота. После этого запустите терминал из этой папки и выполните команду создания node.js проекта:

$ npm init -y
Wrote to /path.../package.json:
{
  "name": "scrape_proj",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Эта команда создает в вашем проекте файл package.json с описанием базовой конфигурации. Этот файл можно дополнить самостоятельно заполнив поля author, description и keywords.

Проект создан, теперь установим дополнительные библиотеки, которые помогут значительно облегчить запуск и настройку всех основных процессов, необходимых для скрейпинга. В этом примере мы будем использовать популярные библиотеки axios, cheerio и json2csv. Каждая из библиотек облегчит один из трех основных этапов, о которых будет сказано в следующей главе.

Установить новые библиотеки в node.js очень просто благодаря менеджеру пакетов, который мы уже загрузили ранее:

$ npm install axios cheerio json2csv

Эта команда создаст в вашем проекте папку node_modules, в которую будут загружены все необходимые для работы библиотек пакеты, а также обновит файл package.json, сохранив в нем информацию об установленных зависимостях.

Три этапа веб-скрейпинга

В любом проекте, в том числе при использовании node.js, реализация процесса скрейпинга состоит из трех этапов:

  1. Отправка HTTP-запросов к нужной странице и получение ответа от сервера;
  1. Парсинг нужных данных из ответа сервера;
  1. Сохранение полученных данных в удобной форме (файл, база данных);

Реализовать первый этап в рамках проекта нам поможет библиотека Axios. В Сети можно найти и другие решения, но Axios представляется наиболее актуальной и надежной альтернативой. С ним вы можете успешно генерировать HTTP-запросы и обрабатывать ответы от веб-серверов.

На втором этапе мы будем использовать Cheerio. Это мощная библиотека упрощающая парсинг HTML-страниц. Особенно удобно будет пользоваться тем, кто уверенно чувствует себя при работе с jQuery, потому что синтаксис для обращения к отдельным элементам веб-страницы в Cheerio и jQuery очень похож.

Третий этап при использовании JavaScript еще проще предыдущих и легко получится с помощью json2csv. С ним мы сохраним результаты парсинга в формате json в csv-файл.

Анализ страницы и выбор селекторов

Чаще всего сбор данных осуществляется с тех или иных интернет-магазинов и других сайтов онлайн-торговли. Но для пробного скрейпинга лучше всего подойдет сайт, специально созданный для проверки на нем корректности работы программ пользователей.

Среди таких сайтов можно выделить Quotes to Scrape и Books to Scrape. Эти сервисы специально созданы чтобы любой желающий мог попробовать скрейпинг без блокировок или нарушений правил сервиса.

Если вам интересно насколько легальным и этичным является веб-скрейпинг, вы можете прочитать нашу статью, посвященную этой теме.

Чтобы облегчить парсинг запрашиваемых веб-страниц удобно использовать CSS-селекторы. По ним можно гарантированно находить HTML-элемент, содержащий требуемую информацию на исследуемой странице при любом количестве вложений тэгов.

Просмотреть селектор для любого элемента в документе довольно просто. Рассмотрим для примера заголовок главной страницы Quotes to Scrape.

  1. Нажимаем правой кнопкой мыши на заголовок страницы, в выпадающем меню выбираем пункт “Посмотреть код”. Это откроет раздел инструментов разработчика в вашем браузере;
  2. В разделе Elements находим этот же заголовок внутри тега h1 и снова кликаем на него правой кнопкой мыши;
  3. В открывшемся меню выбираем пункт Copy;
  4. Среди предлагаемых опций выбираем Copy selector;

Скопированный в результате этого селектор будет выглядеть так:

body > div > div.row.header-box > div.col-md-8 > h1 > a

Использовать подобные селекторы эффективно при парсинге больших веб-страниц со сложной структурой. В некоторых других случаях можно проанализировать состав страницы и использовать более простой селектор. Например, в данном случае на главной странице есть только один h1-элемент. Поэтому работать с объемным селектором в данном случае нет необходимости.

Практические примеры скрейпинга с Node.js

Начинаем с простого: запрос заголовка

Для начала загрузим функционал внешних модулей cheerio и axios в основной файл проекта и сохраним их в переменных для дальнейшего обращения:

const cheerio = require("cheerio");
const axios = require("axios");

В другую переменную сохраним адрес целевой страницы:

const url = "https://quotes.toscrape.com/";

Для отправки GET-запроса в библиотеке Axios предусмотрен метод get(), который выполняется асинхронно, поэтому перед его вызовом необходимо поставить префикс await:

const url = "https://quotes.toscrape.com/";

В этом методе вторым аргументом можно указать дополнительные параметры запроса: http-заголовки, данные для авторизации, подключение к прокси, сетевой протокол, время ожидания ответа сервера и другое. Например, запрос через прокси выглядит так:

const response = await axios.get(url, {
      proxy: 
      {
          "host": "proxy-IP",
          "port": "proxy-port",
          "auth": {
              "username": "proxy-login",
              "password": "proxy-password",
          },
      }
});

Чтобы получить из объекта ответа только полезную информацию - запрошенную веб-страницу без http-заголовков и статуса ответа воспользуемся возможностями библиотеки Cheerio:

const $ = cheerio.load(response.data);

Распарсить нужные данные из элемента по его селектору также очень просто:

const title = $("h1").text();>

Увидеть результат работы скрипта выведем значение переменной title в консоль:

console.log(title);

Работа с HTTP-запросами может быть сопряжена с возникновением ошибок при проблема с сервером на стороне целевого сайта, ограничении доступа к нему или нестабильным соединением со стороны node.js сервера. Поэтому создание GET-запроса необходимо обернуть в try-catch блок, которые позволит вывести в консоль информацию о типе ошибки и продолжить работу программы.

В результате общий код программы будет выглядеть так:

const cheerio = require("cheerio");
const axios = require("axios");
const url = "https://quotes.toscrape.com/";

async function getTitle() {
  try {
    const response = await axios.get(url);
    const document = cheerio.load(response.data);
    const title = document("h1").text();
    console.log(title);
  } catch (error) {
    console.error(error);
  }
}
getTitle();

Код готов, осталось выполнить его с помощью Node.js:

$ node index.js

В результате выполнения программы в консоли появится заголовок сайта:

Quotes to Scrape

Поздравляем! Вы успешно написали свою первую программу на JavaScript для скрейпинга.

Получение данных о товарах

Веб-скрейпинг в большинстве случаев связан со сбором текущих цен на те или иные услуги. Для примера попробуем собрать данные о цена на книги с сайта-тренажера books.toscrape.com. Данные возьмем со страницы с книгами жанра Mystery.

Чтобы понять как получить данные о книгах с этой страницы проанализируем ее HTML-код. Объект каждой книги содержится внутри тэга <article>. Значит можно использовать Cheerio и пройтись циклом по всем данным элементам, чтобы получить требуемую информацию. Для запуска цикла воспользуемся методом each(). Упрощенно цикл будет выглядеть так:

onst books = $("article"); //Selector to get all books
books.each(function () 
           { //running a loop
        title = $(this).find("h3 a").text(); //extracting book title
        console.log(title);//print the book title
            });

Несложно заметить, что удобнее будет хранить целевую информацию о книгах в отдельном массиве в JSON формате пока идет выполнение цикла.

Таким образом финальный код будет выглядеть так:

const cheerio = require("cheerio");
const axios = require("axios");
const mystery = "http://books.toscrape.com/catalogue/category/books/mystery_3/index.html";
const books_data = [];
async function getBooks(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);
 
    const books = $("article");
    books.each(function () {
      title = $(this).find("h3 a").text();
      price = $(this).find(".price_color").text();
      stock = $(this).find(".availability").text().trim();
      books_data.push({ title, price, stock }); //store in array
    });
    console.log(books_data);//print the array
  } catch (err) {
    console.error(err);
  }
}
getBooks(mystery);

Все, что нужно это сохранить код в отдельный файл books.js и запустить его командой node:

$ node books.js

В результате выполнения кода вся информация о книгах будет выведена в консоль. Однако, здесь мы получили книги только с одной страницы. В следующей главе мы разберемся как быть, если на сайте настроена пагинация и нужно загрузить данные с нескольких страниц сразу.

Скрейпинг страниц с пагинацией

Интернет-магазины и другие похожие по структуре веб-сайты используют пагинацию при отображении большого количества объектов. При этом логика разбиения товаров на отдельные страницы на разных сайтах может отличаться. Поэтому основной нюанс, который нужно учесть - это граничный случай последней страницы, на которой нужно остановить цикл.

Решение этой задачи довольно простое: необходимо с помощью все того же селектора проверять значение элемента содержащего ссылку на следующую страницу. Если значение ссылки не пустое, рекурсивно запускаем нашу функцию с новым URL.

Стоит помнить, что в элементе найденном при парсинге содержится относительная ссылка. Чтобы получить абсолютную ссылку для использовании ее как аргумента функции нужно добавить относительную ссылку к переменной содержащей базовый URL. В нашем коде для этого используется переменная baseUrl.

Таким образом для работы с пагинацией в цикл each() достаточно добавить новое условие:

if ($(".next a").length > 0) {
      next_page = baseUrl + $(".next a").attr("href");
      getBooks(next_page); 
}

При достижении последней страницы это условие не выполнится и программа завершит свою работу. Остался последний шаг - сохранить результаты в файл!

Запись данных в CSV-файл

Выводить большие объемы данных в консоль неудобно и нецелесообразно. Потому что их не получится использовать для последующего анализа. Поэтому данные принято сохранять в файл или базу данных. Сохранить данные в CSV-файл с помощью JavaScript очень просто. Мы воспользуемся библиотеками fs и json2csv. FS установлена по умолчанию, а json2csv мы уже установили ранее.

Для использования их в нашем коде инициализируем их, сохранив их объекты в переменные:

const j2cp = require("json2csv").Parser;
const fs = require("fs");

Следующие функции вызовем после выполнения основной части кода, когда данные уже получены и сохранены в массив. Их выполнение как раз создаст файл и запишет в него содержимое массива:

const parser = new j2cp();
const csv = parser.parse(books_data);
fs.writeFileSync("./books.csv", csv);

В итоге наш файл books.js обновится и будет выглядеть так:

const fs = require("fs");
const j2cp = require("json2csv").Parser;
const axios = require("axios");
const cheerio = require("cheerio");
 
const mystery = "http://books.toscrape.com/catalogue/category/books/mystery_3/index.html";
 
const books_data = [];
 
async function getBooks(url) {
  try {
    const response = await axios.get(url);
    const $ = cheerio.load(response.data);
 
    const books = $("article");
    books.each(function () {
      title = $(this).find("h3 a").text();
      price = $(this).find(".price_color").text();
      stock = $(this).find(".availability").text().trim();
      books_data.push({ title, price, stock });
    });
    // console.log(books_data);
    const baseUrl = "http://books.toscrape.com/catalogue/category/books/mystery_3/";
    if ($(".next a").length > 0) {
      next = baseUrl + $(".next a").attr("href");
      getBooks(next);
    } else {
      const parser = new j2cp();
      const csv = parser.parse(books_data);
      fs.writeFileSync("./books.csv", csv);
    }
  } catch (err) {
    console.error(err);
  }
}
 
getBooks(mystery);

Запустить его как всегда можно из консоли средствами Node.js:

$ node books.js

После успешного завершения работы программы в каталоге вашего проекта появится файл books.csv, который можно открыть любым редактором поддерживающим формат csv, например, Microsoft Excel.

Заключение

В этой статье мы привели простой пример использования языка JavaScript для скрейпинга и парсинга данных в Сети. Мы использовали фреймворк Node.js и библиотеки Axios, Cheerio и Json2csv.

Если вы хотите узнать больше о краулинге, скрейпинге и парсинге веб-сайтов, мы подготовили и другие статьи на эту тему:

Комментарии

Войдите, чтобы оставить комментарий
Популярные

Возникла необходимость использовать прокси-сервер для повышения анонимности в интернете? Не знаете, как правильно настроить прокси перед началом работы? В этой статье постараемся ответить на все вопросы, возникающие при первом подключении к сети через единичный прокси-сервер в Windows 10.

Вместе с широкими возможностями Интернет несет в себе и ряд опасностей. Решить данные проблемы можно с помощью технологии OpenVPN, которая предлагает несколько действенных способов скрыть трафик.

Изначально всемирная Сеть задумывалась как пространство без границ, где можно получить абсолютно любую информацию на анонимных началах. Сегодня в разных странах запрещены различные ресурсы.

В современном мире становится сложнее сохранить личные и корпоративные данные в тайне, поэтому вопрос информационной безопасности стоит все острее с каждым днём.

В далеком, по меркам темпов развития информационных технологий, 2015 году компания Google смогла создать искусственный интеллект, способный анализировать состояние вокруг него и делать выводы. Прозвали это чудо DQN, и оно тренировалось в аркадных игра (Пакман, Теннис, Спейс Инвейдерс, Боксинг и прочей классике). Результаты оказались таковы: DQN превзошло в 22 из 49 игр успехи лучших игроков мира!

Новые

Нашумевший в арбитражных кругах браузер Dolphin{anty} привычный инструмент для тех, кто льет трафик через соцсети или сервисы медийной и контекстной рекламы. В статье мы поговорим об этом антидетекте и объясним, как настроить в нём прокси.

С появлением Node.js развитие JavaScript как одного из самых мощных и удобных языков для веб-скрейпинга и парсинга данных значительно ускорилось. Node.js - одна из самых популярных и быстро развивающихся программных платформ. Основное назначение его - выполнение JavaScript кода без участия браузера.

Получение больших объемов данных с веб-сайтов для их последующего анализа играет значительную роль для многих проектов. Анализ структуры целевого ресурса и скрейпинг интересующей информации зачастую сопряжены с проблемой блокировки или ограничения доступа со стороны администрации веб-сайта.

Если вы ищете пакет резидентских или мобильных прокси с возможностью работы с определенной страной или ISP, лучшим решением станет пакет Exclusive mix. С ним вы можете скачать список, содержащий прокси только выбранных вами стран и операторов, гибко фильтруя его под свои нужды.

С чего начать скрейпинг данных в Сети, используя Python? Такой вопрос возникает у многих начинающих специалистов. На начальном уровне этот процесс довольно простой и любой желающий может быстро начать реализовывать свой проект. Однако, для качественной работы над подобной задачей нужно помнить о большом количестве нюансов, в которых не так просто разобраться сразу.

Есть вопросы?

Нажмите сюда и мы с радостью на них ответим