Pull to refresh

Пишем простой парсер web страниц

Reading time3 min
Views31K
Здравствуйте. Меня зовут Сережа. Я хочу рассказать о том, как я писал простейшего вэб паука.
image
Поскольку это некоммерческий проект, созданный исключительно на моём энтузиазме, при работе я руководствовался следующим:

1. Минимум необходимых функций (сканирование web, сохранение необходимого в БД, простенький UI для доступа)
2. 0 финансовых затрат:
— В качестве сервера использую нетбук, который покупал в свое время для учебы acer aspare ONE KAV60, весьма бюджетный даже на момент покупки (2008 год), сейчас его процессора atom в 1600 МГц не хватает даже для нормальной работы в MS OFFICE
— Интернет — проводной домашний. Благо IP уже пол года не менялся, не пришлось заказывать статический
3. Минимум временых затрат. Проект делался после работы и дачи.

В качестве ПО использованы:

  • ОС XUBUNTU
  • Сервер ngINX
  • nodeJS
  • СУБД mySQL
  • Для UI: jQuery, bootstrap3

В рунете есть популярный развлекательный ресурс (назовем его Пикабу — ссылку не даю, дабы не сочли рекламой). Представляет из себя развлекательные посты, размещаемые пользователями и комментарии. Модераторы ресурса жестко (по-моему мнению иногда даже через чур) следят за содержанием комментариев. В результате их работы часто вместо комментария можно увидеть следующее:

image

Наш робот будет через определённые промежутки времени сканировать ресурс в поиске новых комментариев, которые будет вносить в БД, дабы всегда можно было посмотреть, что не понравилось модератору.

Нам потребуются следующие модули:

var jsdom = require("jsdom");
var mysql = require('mysql');
var CronJob = require('cron').CronJob;

В основе нашего робота будет 2 функции:

// * * * Ищем ссылки на страницы
function get_links(){
	jsdom.env('http://pikabu.ru',function(err, window){		
		if (err)
			return false;			
		var page = window.document.getElementsByClassName('to-comments')		
		for (var i=0; i<page.length; i+=2)
			get_comments(page[i].getAttribute('href'));
	})
}

Этой функцией мы запрашиваем главную страницу ресурса и ищем элементы с классом ".to-comments". В них хранятся ссылки на страницы с комментариями. Поскольку эти элементы идут впаре, нам нужен только каждый второй.

В данной функции нам очень помогает модуль jsdom. Он преобразует html код в DOM дерево, в котором мы легко можем найти нужный элемент.

Как мы видим, эта функция вызывает get_comments()

function get_comments(link){	
	jsdom.env(link,function(err, window){		
		if (err)
			return false;		
		var comment = window.document.getElementsByClassName('comment')			
		for (var i=0; i<comment.length; i++){						
			var id = comment[i].getAttribute('data-id');
			var author = comment[i].getElementsByClassName('post_author')[0].textContent;	
			// Если коммент удален
			var block = comment[i].getElementsByClassName('comment_text')[0].getElementsByTagName('span');
			if (block.length > 0 && block[0].textContent.substr(0,11)=='Комментарий'){	
				console.log(block[0].baseURI+'#comment_'+id);		
				continue}			
			var com = comment[i].getElementsByClassName('comment_text')[0].outerHTML.replace(/"/g, '"').replace(/\n|\t/g, '').replace('previews_gif_comm', 'big_size_comm_an');			
			
			var query = 'INSERT IGNORE comments (id, user, comment) VALUES ('+id+', "'+author+'", "'+com+'")';
			DBconnection.query(query, function(err, rows, fields) {
				if (err) throw err;
				});			
			}			
		console.log(new Date()+' DATA ADDED...');	
		});
	
}

Здесь мы также пробегаемся по дереву, ищем элементы с классом «comment», выделяем из них нужные элементы: id комментария, автора, отсеиваем удаленные комменты, убираем спецсимволы, немного переделываем код (убираем превьюшки) и заносим всё это в БД. В таблице comments поле id уникально, поэтому mySQL сама следит, чтобы не было дублированных комментариев.

Нам осталось завести таймер, пробуждающий робота каждые 5 минут. В node.JS это можно реализовать при помощи модуля croneJob — аналог планировщика crone в linux.

	var job = new CronJob('*/5 * * * *', function(){
			get_links();
		});	
	job.start();	

На этом пока всё. Наш паук научился лазить по ресурсу и сохранять комментарии. Если хотите могу написать статью, про вэб интерфейс к этому роботу или про плагин хрома для этого робота.
Tags:
Hubs:
Total votes 26: ↑14 and ↓12+2
Comments8

Articles