Google-подобная архитектура краулера для КазНета

Блог им. yrnt /

На данный момент алгоритм быстрого обхода КазНета я вижу следующим:
1. Список сайтов;
2. Скачиваем главные страницы сайтов. Извлекаем урлы 1 уровня;
3. Скачиваем урлы 2 уровня;
4. Извлекаем сайты из урлов;
5. Обновляем список сайтов.

Он схематически может быть представлен так:

Рассмотрим подробнее каждый пункт алгоритма:

1. Список сайтов

Дан файл sites.txt:


2. Скачиваем главные страницы сайтов. Извлекаем урлы 1 уровня

Процесс распределенный. Количество map-функций зависит от количества серверов в кластере. Код map-функции выглядит следующим образом:
<?php
class Crawler_SiteMapper extends MapReduce_Mapper {

    public function map($sK, array $aV) {
        $sUrl = 'http://' . $sK;
        $oP = new Crawler_Page($sUrl);
        try {
            $oP->open();
            $a = $oP->getLinks();
            foreach ($a as $sUrl1) {
                $oP1 = new Crawler_Page($sUrl1);
                if ($this->filter($oP1->getScheme(), $oP1->getHost())) {
                    $this->emit($sUrl1, array());
                }

            }

            $oP->close();
        } 
        catch (Exception $oE) {
            // do nothing
        }
        
    }
    
}
?>


3. Скачиваем урлы 2 уровня

Процесс распределенный. Количество map-функций зависит от количества серверов в кластере. Код map-функции выглядит следующим образом:
<?php
class Crawler_UrlMapper extends Crawler_SiteMapper {

    public function map($sK, array $aV) {
        $oP = new Crawler_Page($sK);
        try {
            $oP->open();
            $a = $oP->getLinks();
            foreach ($a as $sUrl) {
                $oP1 = new Crawler_Page($sUrl);
                if ($this->filter($oP1->getScheme(), $oP1->getHost())) {
                    $this->emit($sUrl, array());
                }

            }

            $oP->close();
        } 
        catch (Exception $oE) {
            // do nothing
        }

    }

}
?>


4. Извлекаем сайты из урлов

Процесс распределенный. Количество map-функций зависит от количества серверов в кластере. Код map-функции выглядит следующим образом:
<?php
class Crawler_UrlToSiteReducer extends MapReduce_Reducer {

    public function reduce($sUrl, MapReduce_Collection $oV) {
        $this->emit($sUrl, array());
    }

}
?>


5. Обновляем список сайтов

Удаляем sites.txt. Переименовываем результат reduce-функции в sites.txt.

Заключение

Я имею опыт в написании краулеров. Ботлнеком были сеть и процессор. Предложенная google-ом архитектура красиво устраняет ботлнеки через распределенность. Еще одним плюсом является малое количество кода и его наглядность.

17 комментариев

allasc
проверочку для урлов незабудте поставить
относятся ли они к казнету
а то после 5 итерации будете скоблить весь мир, прям как гугл… денег не хватит
yrnt
if ($this->filter($oP1->getScheme(), $oP1->getHost())) {

Такая строчка имеется.
_AXE_
Зачем это всё?
yrnt
Для массового сбора контента.
_AXE_
Я понял. Вопрос, зачем это нужно? У меня разрыв шаблона: делаем поискового бота (ого, серьёзно), и опа-на список сайтов в .txt.
yrnt
А что там должно быть вместо txt?
majesty
Для прототипа txt — в самый раз. В продакшене вместо файлов можно подложить что угодно.
p0is0n
Очень интересная статья, многое узнал о map-reduce, о том как полезно строить кластера на php и как получить с этого огромный профит.
Claus
Хернёй ненужной занимаетесь. Делал я подобные анализаторы доменов и контента, но в классификацией доменов по тематикам (углубленный анализ контента и его принадлежности к какой то категории) и составлял публичные списки для всяких сервисов. Естественно всё это было на автоматике, но за 5ть лет только один клиент обратился с предложением что то приобрести, когда всё это было бесплатно. Тема раскрыта на 5%, и пользы в дальнейшем иметь не будет…
yrnt
Каким образом производилась классификация и составлялись списки?
endeveit
Ернат, в чем соль?
Скачать казнет — не проблема, я писал подобный краулер еще году в 2007 на перле.
Самый сок в выделении из документа содержимого, поиска по этому содержимому и в создании оптимального алгоритма ранжирования.
Как у вас это реализовано и реализовано ли? :)
yrnt
1. Умеет распределенно краулить html-ки
2. Умеет распределенно вытаскивать из html-ок контент, т.е. отсекаем меню, баннеры и тп;
3. Умеет распределенно ранжировать;
4. Умеет распределенно строить поисковый индекс;
5. Умеет распределенно искать по поисковому индексу.

Соль в том, что раньше это было на одном процессоре,
а теперь можно выполнять на нескольких.
allasc
sozdik смотри ненароком не прокраули :))))) а то они в суд подадут :))))))
endeveit
Что-то уведомления об ответе на комментарий не приходят.
Распределенность — это здорово, но не интересно.
Если не секрет, расскажи про все остальное.
Как вытаскиваете контент? Каждый сайт попадает в «песочницу», в которой определяются статичные блоки сайта и которые затем удаляются? Или, может, у вас нейронная сеть с обучением учителем? Или используете какие-то эвристики вроде «Largest Block of String» или что-то еще?
Как строите и храните поисковый индекс? Собственное решение или надстройка над существующими продуктами? Умеете работать с казахской морфологией или нет?
yrnt
Распределенность — это здорово, но не интересно.
Без нее все медленно.

Как вытаскиваете контент? Каждый сайт попадает в «песочницу», в которой определяются статичные блоки сайта и которые затем удаляются? Или, может, у вас нейронная сеть с обучением учителем? Или используете какие-то эвристики вроде «Largest Block of String» или что-то еще?
Сейчас, вариант с нейронной сетью, но решил отказаться от него.

Как строите и храните поисковый индекс?
Распределенная хэш-таблица в map/reduce движке, но с ней проблема — съедает иноды. В MVC-движке по аналогии с Lucene.

Собственное решение или надстройка над существующими продуктами?
Свое.

Умеете работать с казахской морфологией или нет?
Написал стеммер под русский язык. Насчет казахского не думал.
yrnt
У меня встречный вопрос. В thenews.kz парсинг rss-потоков производится автоматически. Каждая статья попадает в определенную категорию. Я присмотрелся к алгоритму и заметил, что там скорее всего не баес. Для бэггинга и бустинга проект мелковат. Поэтому интересно, как там работает классификация?
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.