Страницы

суббота, 7 декабря 2013 г.

Server side jQuery. Парсим HTML.

Кому приходилось парсить HTML, сможет оценить Node.js модуль cheerio. Такая серверная реализация jQuery, удобный инструмент. Расскажу как его можно использовать. В качестве примера вытащим имена всех авторов сайта VR-Online, опубликованных на главной странице. Думаю они не против :). Исхожу из того, что Node.js и npm у вас уже установлены.

Для начала откроем в браузере VR-Online и найдем код ссылки на профиль какого-нибудь пользователя:

Стало быть нас интересует тэг "a", который находится внутри тэга "p" в контексте класса .meta:

Пишем нехитрый код:
var request = require('request'),
    cheerio = require('cheerio');
  
request('http://www.vr-online.ru', function(err, res, body) {
  if (!err && res.statusCode == 200) { 
    var $ = cheerio.load(body);      
    $('p a','.meta').each(function() {      
      console.log(this.text());      
    });
  }
});

Не забываем установить модули cheerio и request - классный модуль для выполнения http/https запросов:
npm install cheerio request

Выполняем:

Как-то неинтересно получилось. Предлагаю написать простой http-сервер, который будет раз в минуту выполнять запросы, кэшировать данные и раздавать их из кэша в виде html-страницы, содержащей ссылки на профили авторов, а также количество постов каждого автора.
var request = require('request'),
    cheerio = require('cheerio'),
    http = require('http'),
    url = 'http://www.vr-online.ru';

var cache = {  
  push: function(o) {
    for (var i=0; i<this.data.length; i++) {
      if (this.data[i]['name'] === o.name) {
        this.data[i]['count']++;
        return;
      }
    }
    o['count'] = 1;
    this.data.push(o);
  },
  build: function() {
    this.page = '<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><body><ul>';
    for (var i=0; i<this.data.length; i++) {
      this.page = this.page + '<li><a href="http://' + url + this.data[i]['url'] + '">' + 
          this.data[i]['name'] + '</a> - ' + this.data[i].count + '</li>';
    }
    this.page += '</ul></body></html>';
    console.log('--- Cache is built ---');    
  }
};

function buildCache() {
  console.log('\n--- Building cache ---\n');
  request(url, function(err, res, body) {
    if (!err && res.statusCode == 200) {
      var $ = cheerio.load(body);
      cache.data = [];
      $('p a','.meta').each(function() {        
        cache.push({name: this.text(), url: this.attr('href')});
      });
      cache.build();
    }
  });
}

buildCache();
setInterval(function() {buildCache();}, 60000);

http.createServer( function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});  
  res.end(cache.page);
}).listen('3000', '127.0.0.1');
console.log('--- Server started on http://localhost:3000 ---\n');

Запускаем наш сервер, идем по адресу http://localhost:3000 ...

Через пару минут обращаем внимание на то, что данные обновляются:

Можно заливать на хостинг :).

В качестве домашнего задания предлагаю попробовать подобным образом к ссылке на профиль автора добавить его аватар.

На этом прощаюсь, и да пребудет с вами сила :).