Простой гусеничный ход, использующий Cheerio
Это моя формула сделать простой сканер в Node.js. Это основная причина желания манипулировать DOM на стороне сервера и, возможно, именно поэтому вы сюда попали.
Сначала используйте request
, чтобы загрузить страницу для анализа. Когда загрузка будет завершена, обработайте ее до cheerio
и начните манипулирование DOM так же, как с использованием jQuery.
Рабочий пример:
var
request = require('request'),
cheerio = require('cheerio');
function parse(url) {
request(url, function (error, response, body) {
var
$ = cheerio.load(body);
$('.question-summary .question-hyperlink').each(function () {
console.info($(this).text());
});
})
}
parse('http://stackoverflow.com/');
Этот пример выведет на консоль все главные вопросы, отображаемые на домашней странице SO. Вот почему я люблю Node.js и его сообщество. Это не могло быть легче, чем это: -)
Установить зависимости:
npm запрос на установку cheerio
И запустить (при условии, что приведенный выше скрипт находится в файле crawler.js
):
узел crawler.js
Кодирование
Некоторые страницы будут содержать неанглийский контент в определенной кодировке, и вам нужно будет расшифровать его до UTF-8
. Например, страница на бразильском португальском (или любом другом языке латинского происхождения), вероятно, будет закодирована в ISO-8859-1
(a.k.a. "latin1"). Когда требуется декодирование, я говорю request
не интерпретировать содержимое каким-либо образом и вместо этого использую iconv-lite
для выполнения работы.
Рабочий пример:
var
request = require('request'),
iconv = require('iconv-lite'),
cheerio = require('cheerio');
var
PAGE_ENCODING = 'utf-8'; // change to match page encoding
function parse(url) {
request({
url: url,
encoding: null // do not interpret content yet
}, function (error, response, body) {
var
$ = cheerio.load(iconv.decode(body, PAGE_ENCODING));
$('.question-summary .question-hyperlink').each(function () {
console.info($(this).text());
});
})
}
parse('http://stackoverflow.com/');
Перед запуском установите зависимости:
npm запрос на установку iconv-lite cheerio
И наконец:
node crawler.js
по ссылкам
Следующим шагом будет переход по ссылкам. Скажем, вы хотите перечислить все постеры с каждого главного вопроса на SO. Вы должны сначала перечислить все главные вопросы (пример выше), а затем ввести каждую ссылку, анализируя страницу каждого вопроса, чтобы получить список вовлеченных пользователей.
Когда вы начинаете переходить по ссылкам, может начаться обратный вызов ада . Чтобы избежать этого, вы должны использовать какие-то обещания, фьючерсы или что-то еще. Я всегда держу async в своем инструментальном поясе. Итак, вот полный пример сканера, использующего async:
var
url = require('url'),
request = require('request'),
async = require('async'),
cheerio = require('cheerio');
var
baseUrl = 'http://stackoverflow.com/';
// Gets a page and returns a callback with a $ object
function getPage(url, parseFn) {
request({
url: url
}, function (error, response, body) {
parseFn(cheerio.load(body))
});
}
getPage(baseUrl, function ($) {
var
questions;
// Get list of questions
questions = $('.question-summary .question-hyperlink').map(function () {
return {
title: $(this).text(),
url: url.resolve(baseUrl, $(this).attr('href'))
};
}).get().slice(0, 5); // limit to the top 5 questions
// For each question
async.map(questions, function (question, questionDone) {
getPage(question.url, function ($$) {
// Get list of users
question.users = $$('.post-signature .user-details a').map(function () {
return $$(this).text();
}).get();
questionDone(null, question);
});
}, function (err, questionsWithPosters) {
// This function is called by async when all questions have been parsed
questionsWithPosters.forEach(function (question) {
// Prints each question along with its user list
console.info(question.title);
question.users.forEach(function (user) {
console.info('\t%s', user);
});
});
});
});
Перед запуском:
npm запрос на установку async cheerio
Запустить тест:
узел crawler.js
Пример вывода:
Is it possible to pause a Docker image build?
conradk
Thomasleveil
PHP Image Crop Issue
Elyor
Houston Molinar
Add two object in rails
user1670773
Makoto
max
Asymmetric encryption discrepancy - Android vs Java
Cookie Monster
Wand Maker
Objective-C: Adding 10 seconds to timer in SpriteKit
Christian K Rider
И вот что вы должны знать, чтобы начать создавать свои собственные сканеры: -)
используемые библиотеки