Парсим сайт с помощью Node.js
Парсинг сайтов (web scraping) можно использовать для создания сводки новостных лент, пополнения базы email-адресов, сравнения цен и других целей. В нашей статье мы поговорим о парсинге через API сайтов — данный подход отличается простотой, ведь парсинг всей страницы не требуется. В большинстве случаев этот подход весьма неплох. Но стоит учесть, что он может не сработать, если владелец сайта установит специальные настройки.
Как это функционирует?
Алгоритм следующий: — парсер посылает веб-странице get-запрос; — парсер получает данные в виде HTML/XML; — осуществляется извлечение данных в желаемом формате.
Чтобы загружать файлы через консоль нам подойдёт утилита Wget, однако вы вправе выбрать и другой инструмент на своё усмотрение.
Для работы нам подойдёт программный пакет osmosis, который написан на Node.js. Пакет включает в себя небольшой http-обработчик и селектор css3/xpath. В принципе, существуют и другие фреймворки типа Webdriver, но они не потребуются.
Настройка проекта
Итак, приступим:
1. Выполняем установку Node.js, которая поставляется совместно с npm (менеджером пакетов).
2. Выполняем создание новой папки, пусть это будет webscrap, но можете использовать и любое другое имя.
3. Переходим в эту папку командой
Вот как будет в итоге выглядеть наш 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, а потом запустим консольную команду
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-страницу, используя инструменты разработчика;
— мы проверяем блок, где находится слово (в нашем случае это
Как увеличить число страниц при релевантном поиске?
Тут придётся добавить цепочку вызовов (chaining method) и вычислить у тега anchor (
Что делаем:
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-адреса и названия приложений, перемещаясь последовательным образом посредством метода
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)
Вышеописанный код можем комбинировать с методом
Итак, давайте сохраним данные в формате 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».