Web scraping при помощи node.js, request и cheerio

Published by Leave your thoughts

Web scraping – это технология извлечения информации с веб-сайтов.

В этом руководстве показано, как выполнить scraping на примере первой страницы Hacker News, чтобы получить все самые популярные ссылки, а также их метаданные: например, название, URL и количество полученных комментариев. Для этого применяется техника извлечения данных страницы при помощи node.js и модуля cheerio.

Cheerio – это легковесный, быстрый и гибкий модуль на основе jQuery.

Также в руководстве используется модуль request – упрощённый HTTP-клиент.

Требования

Чтобы следовать руководству, нужно обладать навыками работы с node.js и jQuery, а также уметь выполнять основные задачи Linux (например, работать с SSH).

Также нужно предварительно установить node.js.

Примечание: Полезные инструкции по установке и использованию node.js можно найти в специальном разделе нашего сайта.

Установка модулей cheerio и request

Чтобы установить необходимые модули с помощью NPM, используйте команду:

npm install request cheerio

Эта команда установит модули только в текущий рабочий каталог.

Чтобы установить модули глобально, запустите:

npm install -g request cheerio

Создайте файл scrape.js и вставьте в него следующий код:

var request = require('request');
var cheerio = require('cheerio');

Он загрузит зависимости модулей.

Web scraping страницы

Теперь загрузите первую страницу Hacker News при помощи простого запроса и откройте её HTML-код, если не возникло никаких ошибок, а код состояния равен 200.

Вставьте в файл следующие строки:

request('https://news.ycombinator.com', function (error, response, html) {
if (!error && response.statusCode == 200) {
console.log(html);
}
});

Попробуйте запустить крипт при помощи node scrape.js. На экране появится HTML-код в окне терминала.

Чтобы понять, как извлечь необходимые метаданные, нужно знать, как структурированы элементы в HTML-коде. Предпочтительнее всего использовать инструменты веб-разработчика, встроенные в Google Chrome, чтобы осмотреть целевой элемент веб-страницы; для этого достаточно просто щелкнуть правой кнопкой мыши на нем и выбрать Inspect element (или Просмотр кода элемента).

Ознакомьтесь со структурой элементов кода.

В этом примере для того, чтобы быстро извлечь данные 30 топ-ссылок страницы, достаточно просто выбрать каждый элемент «span» с дополнительным классом «comhead» и каждый сопутствующий элемент «а»; это можно сделать с помощью специальной функции JQuery API — prev().

Измените код запроса следующим образом:

request('https://news.ycombinator.com', function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('span.comhead').each(function(i, element){
var a = $(this).prev();
console.log(a.text());
});
}
});

Как видите, запустив данный код, вы получили список из 30 названий. Снова отредактируйте код запроса, чтобы получить остальные метаданные:

request('https://news.ycombinator.com', function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
$('span.comhead').each(function(i, element){
var a = $(this).prev();
var rank = a.parent().parent().text();
var title = a.text();
var url = a.attr('href');
var subtext = a.parent().parent().next().children('.subtext').children();
var points = $(subtext).eq(0).text();
var username = $(subtext).eq(1).text();
var comments = $(subtext).eq(2).text();
// Our parsed meta data object
var metadata = {
rank: parseInt(rank),
title: title,
url: url,
points: parseInt(points),
username: username,
comments: parseInt(comments)
};
console.log(metadata);
});
}
});

Этот код выполняет следующие действия:

  • Выбирает предыдущий элемент:

var a = $(this).prev();

  • Получает ранг путем разбора элемента на два уровня выше элемента «а»:

var rank = a.parent().parent().text();

  • Разбирает название ссылки:

var title = a.text();

  • Разбирает атрибут href элемента «а»:

var url = a.attr('href');

  • Получает подтекст следующей строки HTML-таблицы:

var subtext = a.parent().parent().next().children('.subtext').children();

  • Извлекает соответствующие данные:

var points = $(subtext).eq(0).text();
var username = $(subtext).eq(1).text();
var comments = $(subtext).eq(2).text();

Хранить извлечённые данные для дальнейшей их обработки можно в MongoDB или Redis.

Так выглядит полный код файла scrape.js:

var request = require('request');
var cheerio = require('cheerio');
request('https://news.ycombinator.com', function (error, response, html) {
if (!error && response.statusCode == 200) {
var $ = cheerio.load(html);
var parsedResults = [];
$('span.comhead').each(function(i, element){
// Select the previous element
var a = $(this).prev();
// Get the rank by parsing the element two levels above the "a" element
var rank = a.parent().parent().text();
// Parse the link title
var title = a.text();
// Parse the href attribute from the "a" element
var url = a.attr('href');
// Get the subtext children from the next row in the HTML table.
var subtext = a.parent().parent().next().children('.subtext').children();
// Extract the relevant data from the children
var points = $(subtext).eq(0).text();
var username = $(subtext).eq(1).text();
var comments = $(subtext).eq(2).text();
// Our parsed meta data object
var metadata = {
rank: parseInt(rank),
title: title,
url: url,
points: parseInt(points),
username: username,
comments: parseInt(comments)
};
// Push meta-data into parsedResults array
parsedResults.push(metadata);
});
// Log our finished parse results in the terminal
console.log(parsedResults);
}
});

Tags: , ,

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>