Парсим сайт с помощью Node.js | OTUS

Парсим сайт с помощью Node.js

otus_Posts_26may_VK_1000x700_2-20219-dbef72.jpg

Парсинг сайтов (web scraping) можно использовать для создания сводки новостных лент, пополнения базы email-адресов, сравнения цен и других целей. В нашей статье мы поговорим о парсинге через API сайтов — данный подход отличается простотой, ведь парсинг всей страницы не требуется. В большинстве случаев этот подход весьма неплох. Но стоит учесть, что он может не сработать, если владелец сайта установит специальные настройки.

Как это функционирует?

Алгоритм следующий: — парсер посылает веб-странице get-запрос; — парсер получает данные в виде HTML/XML; — осуществляется извлечение данных в желаемом формате.

Чтобы загружать файлы через консоль нам подойдёт утилита Wget, однако вы вправе выбрать и другой инструмент на своё усмотрение.

Для работы нам подойдёт программный пакет osmosis, который написан на Node.js. Пакет включает в себя небольшой http-обработчик и селектор css3/xpath. В принципе, существуют и другие фреймворки типа Webdriver, но они не потребуются.

Настройка проекта

Итак, приступим: 1. Выполняем установку Node.js, которая поставляется совместно с npm (менеджером пакетов). 2. Выполняем создание новой папки, пусть это будет webscrap, но можете использовать и любое другое имя. 3. Переходим в эту папку командой cd webscrap. 4. Осуществляем запуск из консоли командой npm init, чтобы создать файл package.json. 5. Выполняем npm i osmosis --save — это обеспечивает установку пакета для парсинга. Дополнительных зависимостей не будет (только от обработчика и селектора). 6. Открываем package.json, потом создаём новый стартовый скрипт — он нам нужен для последующего выполнения команды npm start.

Вот как будет в итоге выглядеть наш package.json:

{
      "name": "webscrap",
      "version": "1.0.0",
      "main": "index.js",
      "scripts": {
        "start": "node index"
      },
      "dependencies": {
        "osmosis": "^1.1.2"
      }
}

Теперь потребуется создать файл index.js, в котором и будем работать.

Парсинг информативного заголовка в Google

Приведём базовый пример для ознакомления с пакетом и запуском первого Node-скрипт. Давайте поместим нижеследующий код в файл index.js, а потом запустим консольную команду npm start. Эта команда выведет заголовок veb-страницы:

const osmosis = require('osmosis');
osmosis
    .get('www.google.com')
    .set({'Title': 'title'})   // альтернатива: `.find('title').set('Title')`
    .data(console.log)  // выведет {'Title': 'Google'}

Теперь давайте разберём, что выполняют методы. Первый (get) получает veb-страницу в сжатом формате. Второй (set) выбирает элемент заголовка, который представлен в виде css3-селектора. Третий (data с console.log) осуществляет вывод. Кроме того, set принимает в качестве аргумента строки.

Как получить релевантные результаты в Google?

Представьте, что вы желаете получить результаты по такому ключевому слову, как analytics. Что делаем:

osmosis
    .get('https://www.google.co.in/search?q=analytics')
    .find('#botstuff')
    .set({'related': ['.card-section .brs_col p a']})
    .data(function(data) {
        console.log(data);
    })

Вот, собственно говоря, и всё. Данный код извлечёт соответствующие ключевые слова с 1-й страницы результатов поиска. Потом он поместит слова в массив, после чего запишет их в лог в консоли. Логика тут следующая: — мы анализируем veb-страницу, используя инструменты разработчика; — мы проверяем блок, где находится слово (в нашем случае это div #botstuff) и выполняем его сохранение в массив посредством селектора .card-section .brs_col p a, который сможет найти на странице все соответствующие ключевые слова.

Как увеличить число страниц при релевантном поиске?

Тут придётся добавить цепочку вызовов (chaining method) и вычислить у тега anchor (<a>) атрибут href. Давайте ограничимся тремя страницами, чтобы Google не подумал, что мы бот. Если хотите выставлять время между парсингом соседних страниц, добавьте метод .delay(ms) после каждого .paginate().

Что делаем:

osmosis
   .get('https://www.google.co.in/search?q=analytics')
   .paginate('#navcnt table tr > td a[href]', 3)
   .find('#botstuff')
   .set({'related': ['.card-section .brs_col p a']})
   .data(console.log)
   .log(console.log) // включаем логи
   .error(console.error) // на случай ошибки

Как парсить адреса эл. почты с Shopify?

Теперь соберём email-адреса и названия приложений, перемещаясь последовательным образом посредством метода .follow. А потом помечаем нужные селекторы в консоли:

osmosis
   .get('http://apps.shopify.com/categories/sales')
   .find('.resourcescontent ul.app-card-grid')
   .follow('li a[href]')
   .find('.resourcescontent')
   .set({
       'appname': '.app-header__details h1',
       'email': '#AppInfo table tbody tr:nth-child(2) td > a'
    })
   .log(console.log)   // включить логи
   .data(console.log)

Вышеописанный код можем комбинировать с методом .paginate — это позволит полностью собрать весь контент (правда, вас могут и заблокировать).

Итак, давайте сохраним данные в формате json:

const fs = require('fs');
let savedData = [];
osmosis
   .get(..).find(..).follow(..).find(..)
   .set(..)
   .log(console.log)
   .data(function(data) {
      console.log(data);
      savedData.push(data);
   })
   .done(function() {
      fs.writeFile('data.json', JSON.stringify( savedData, null, 4), function(err) {
        if(err) console.error(err);
        else console.log('Data Saved to data.json file');
      })
   });

На этом всё, вы же продолжайте экспериментировать. И оставляйте комментарии!

Источник — «Web Scraping in Node.js with Multiple Examples».

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто