Парсинг сайтів за допомогою Node.js: стисле керівництво з прикладами


Дізнайтесь більше про нові кар'єрні можливості в EchoUA. Цікаві проекти, ринкова оплата, гарний колектив. Надсилайте резюме та приєднуйтеся до нас.

У цій статті ми ознайомимося з парсингом сайтів (web scraping), який можна використати, наприклад, для поповнення бази email-адрес, створення зведення новинних стрічок, порівняння цін на один продукт серед декількох комерційних ресурсів або витягання даних з пошукових машин.

 

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

Як це працює?

Приблизно так: парсер посилає сторінці get-запит, отримує дані у вигляді HTML / XML і витягає їх у бажаному форматі. Для завантаження файлів через консоль підходить утиліта WGET, але можна вибрати і будь-який інший відповідний інструмент на просторах Мережі.

Ми використовуватимемо написаний для Node.js програмний пакет osmosis, що має селектор css3/xpath і невеликий http-обробник. Є й інші фреймворки типу Webdriver і CasperJS, але зараз вони нам не знадобляться.

Налаштовуємо проект

  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. Вона виведе заголовок веб-сторінки:

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

Розберемо, що роблять методи. Перший метод get отримує веб-сторінку у стислому форматі. Наступний метод 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); })

От і все. Цей код витягне всі відповідні ключові слова з першої сторінки результатів пошуку, помістить їх в масив і запише у лог в консолі. Логіка, що стоїть за цим, така: ми спочатку аналізуємо веб-сторінку через інструменти розробника, перевіряємо блок, у якому знаходиться слово (в даному випадку це div #botstuff), і зберігаємо його в масиві через селектор .card - section .brs_col p a, який знайде всі відповідні ключові слова на сторінці.

Збільшуємо кількість сторінок за релевантного пошуку

Для цього треба додати ланцюжок викликів (chaining method), обчисливши атрибут href у тега anchor (). Ми обмежимося п’ятьма сторінками, щоб Google не сприйняв нас за бота. Якщо необхідно виставити час між парсингом сусідніх сторінок, додаємо метод .delay (ms) після кожного .paginate ().

osmosis .get ('https://www.google.co.in/search?q=analytics') .paginate ('#navcnt table tr > td a[href]', 5).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”

Київ, Харків, Одеса, Дніпро, Запоріжжя, Кривий Ріг, Вінниця, Херсон, Черкаси, Житомир, Хмельницький, Чернівці, Рівне, Івано-Франківськ, Кременчук, Тернопіль, Луцьк, Ужгород, Кам'янець-Подільський, Стрий - за статистикою саме з цих міст програмісти найбільше переїжджають працювати до Львова. А Ви розглядаєте relocate?


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *