Здравствуйте. Меня зовут Сережа. Я хочу рассказать о том, как я писал простейшего вэб паука.
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();	

На этом пока всё. Наш паук научился лазить по ресурсу и сохранять комментарии. Если хотите могу написать статью, про вэб интерфейс к этому роботу или про плагин хрома для этого робота.
Поделиться с друзьями
-->

Комментарии (8)


  1. VGrabko
    07.09.2016 17:53
    +2

    Это не поисковой бот, а простейший парсер.


    1. uonick
      08.09.2016 03:35

      О чем и сказано в заголовке поста =)


      1. VGrabko
        08.09.2016 11:54
        +1

        он обновил заголовок лол


    1. Lure_of_Chaos
      08.09.2016 19:28

      А где парсер-то? Это примитивный граббер… а парсер-то у нас готовый jsdom.
      Дожили… «Как написать ОС: include 'os';»!


      1. VGrabko
        09.09.2016 00:28

        я вообще не из node тусовки. В Go всё сложнее (там не дают уже готовое dom дерево). Возможно я и не прав в какой-то мере


      1. Seroja_Moroz
        09.09.2016 03:27

        Так, что же я написал ?)


  1. ice2heart
    08.09.2016 09:07

    Выдергивать клубничку до модератора.


  1. Cubus
    08.09.2016 13:57

    FUKKEN SAVED?