пятница, 4 февраля 2011 г.

По быдлокодим

Собственно попался в руки nodejs.
Прикольно. Была давнишняя идея сграбить с сайта goproblems.com задачки. Собственно кто не знает, что такое Го, тому сюда
Ну а раз знакомство, то почему бы и нет. Есть два интереса с двух сторон, пожалуй можно за пару часов и разобраться. С js я немного знаком, так что проще.
Как собирать nodejs и npm, я может чуть позже расскажу. Пока всё же вещь ещё во многом сырая, на свой страх и риск, за кружечкой чего-нибудь.


var httpAgent = require('http-agent'),
jsdom = require('jsdom'),
sys = require('sys');
fs = require('fs');
// Создаем массив относительных путей
var urls = Array()
for (i=1;i<14528;i++) {urls.push('?id='+i);} // 14528 - кол-во известных номеров задач

// Алгоритм можно улучшить, а именно ходя по ссылкам "вперед" и "назад" в задачах.
// Но пусть будет в лоб, да не обидятся на меня ребята с сайта.

// Вторым параметром передаём массив относительных путей
var agent = httpAgent.create('goproblems.com/prob.php3/', urls);

agent.addListener('next', function (e, agent_res) {
// Создаём DOM-дерево из текста страницы
// Если тут ругается, то смотреть на установку libxmljs
var window = jsdom.jsdom(agent_res.body).createWindow();
// Здесь мы подключаем файл jQuery. У меня он лежит в тут же.
jsdom.jQueryify(window, './jquery-1.5.min.js', function (window, jQuery) {
// jQuery загружен, дальше ищем по телу документа
// Собственно each не нужен, но кусок был нагло выдран из контекста
jQuery('body').each(function () {
var sgf = jQuery(this).find('param[name|="sgf"]').val();
if (sgf) {
var id = jQuery(this).find('param[name|="id"]').val();
var difficult = jQuery(this).find("td.prob:contains('Difficulty:')").next().text();
// дальше обработчик строки с данными о сложности
var re = /(\w+)\s(\w+)/;
// Пишем в файл и срём в консоль
fs.writeFile(id+'_('+difficult.match(re)[0]+').sgf', sgf,function(err){
if (err) throw err;
console.log(id+'_('+difficult.match(re)[0]+').sgf saved!');
});
}
});

agent.next();

});

});

agent.addListener('stop', function (agent) {
sys.puts('the agent has stopped');
});

// Запускаем
agent.start()

Часть кода было нагло содрано и немного адаптированно, архитектура хромает. Но дело делает. С задачей справляется. Тем более, что для себя.