Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> грабер, помогите с алгоритмом 
:(
    Опции темы
burakov
Дата 24.3.2011, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет



Нужно написать простой грабер на перл
Ну то есть просто собрать ссылки и вытянуть текстовую часть в файлы по-странично. 
Но страниц много, то есть порядка 40000 и более (до конца так и не посчитал)

я тут для себя накидал вот такую схему: прокомментирую все в коде


Код


my $start_url = 'http://supercatalog.ru'; 
my @global_url = (); #глобальный массив ссылок, откуда будем делать shift
my @global_url_chk = (); #массив ссылок, по которому проверяю была ли уже ссылка, чтобы два раза контент не тянуть

push (@global_url, $start_url); #Кладу в массив стартовый url

while (scalar (@global_url) > 0) {
    
    print scalar (@global_url)."\n"; 
    my $url = shift (@global_url); 
    print $url."\n";
    
    my $content1 = get_content ($url);
    my $content2 = $content1; 
    my $clear_str = clear_str -> new ($content2); 
    $content2 = $clear_str -> delete_1 () ;
    $clear_str = undef;
    
    my $pattern = 'href="(\/.+?)"'; # шаблон для ссылки
    
    while ($content2 =~ /$pattern/ig) {
        my $str = $1;
        $str = $start_url.$str; 
        
        my $status = 'nok'; 
        foreach (@global_url_chk) {  #проверяю если ссылки еще не встречалось, тогда ниже положу ее в глобальный массив для шифта и ее же положу в Chk, чтобы впоследствии не повторять
            if ($_ eq $str) {
                $status = 'ok'; 
                last;
            }
        }
        
        if ($status eq 'ok') {
            $status = 'nok'; 
        } else {
            push (@global_url_chk, $str); 
            push (@global_url, $str); 
        }
    }
    
    my $file = get_file_name ();
    print $file."\n";
    print "\n\n";
    content_to_file ($dir_result_html.'/'.$file, $content1);        
}


Ну вообщем парсер работает.

Вопрос вот в чем 
как кто проверяет ссылки на повтор? (чтобы контент не задваивать), я сначала вместо @global_url_chk
делал глобальную переменную $global_url_chk global_url_chk .' '.$url (т.е. наращивал ее ) и regexp проверял наличие в строки url - но оказалось, что это очень медленно, с массивом вроде бы быстрее - может потому что делаем сравнение по "eq", а регулярные выражения работает медленнее

Но в случае большого сайта, что массив, что строковая переменная вырастет до непонятных размеров??  и что нибудь сбойнет? Так например , я сначала написал грабер рекурсивно вызывая подпрограмму и столкнулся на больших сайтах с проблемой глубины рекурсии (на маленьких понятно это не влазило)

Может у кого есть пример сто % рабочего грабера на perl в студию, чтобы подсмотреть???

Спасибо.


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
ming
Дата 24.3.2011, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 97
Регистрация: 30.1.2009
Где: Новосибирск

Репутация: нет
Всего: 3



уникальность обычно проверяется с помощью хэшей.
Код

my %unique_urls;
my $url = "Maybe not unique url";
...
# пихаем урл в хэш в качестве ключа. то, что используется в качестве значения (здесь: 1) не играет роли.
$unique_urls{$url} = 1;

# запрашиваем список уникальных урлов (а они уникальны, так как в хэше не бывает двух одинаковых ключей)
my @urls = keys %unique_urls;


правда есть одно НО - урлы "google.ru" , "google.ru/" , "www.google.ru" и т.п. будут считаться неуникальными хотя на самом деле указывают на один и тот же документ.

хэш из 40 тысяч элементов наверняка уместится в памяти.

Если элементов существенно больше (сотни тысяч, миллионы), то тогда нужно либо 
1) использовать БД (SQL) и перед вставкой нового урла делать запрос, проверяя не присутствует ли уже этот УРЛ в базе.
2) привязывать хэш к файлу (например http://search.cpan.org/~cangell/Tie-File-A...File/AsHash.pm)
3) иной способ


Это сообщение отредактировал(а) ming - 24.3.2011, 20:50
PM MAIL ICQ Jabber   Вверх
vivu
Дата 24.3.2011, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 3.11.2009

Репутация: нет
Всего: нет



Хотел бы ещё добавить про хеширование ссылок. Т.е. запихивать в хеш, не огромную строку урла, а компактное представление этой строки. И элегантнее и искать должно быстрее.

Код

use Digest::MD5 qw(md5 md5_hex md5_base64);

my $digest = md5_base64($url);

my %uniq = ();
$uniq{ $digest } = 1;


PM MAIL   Вверх
infarch
Дата 29.3.2011, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



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

Добавлено через 2 минуты и 15 секунд
зы. Есть риск выкачать весь интернет, так как почти наверняка будут внешние ссылки, а там потянется сайт за сайтом smile Сделайте проверку на внешние ссылки.
PM MAIL   Вверх
burakov
Дата 29.3.2011, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет



Свет вырубят связь пропала - это очень актуально,
а я вот допустим никак не врублюсь, как организовать грабер с дограбкой?
Кто такой писал подскажите хотя бы алгоритм?

Ведь все равно уникальные ссылки, которые стянули в файл (хэш, массив, строку) накапливаем постепенно, получая контент, начиная со стартовой страницы (то есть можно конечно сказать, что если такой файл, есть то заново не сохраняй) но по сути, то контент все равно приходится заново получать...

Как организовать грабер с дограбкой в случае энергетического коллапса



--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
infarch
Дата 30.3.2011, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Как я такое делал могу в общих чертах описать. Для каждого урла есть запись в базе данных, она имеет статус - новый, готов, провален. При старте скрипта извлекается n новых записей, они кидаются в очередь откуда извлекаются и обрабатываются в разных потоках. Обработка это запрос по имеющемуся урлу и необходимые манипуляции с полученым контентом. Если запрос провален, меняем статус в базе. Если ок - опять таки ставим статус, сохраняем результат. Подошли к концу n записей в очереди - извлекаем очередную пачку и снова в работу. В процессе обработки могут создаваться новые записи в базе, само собой. Вот примерно так...
PM MAIL   Вверх
burakov
Дата 30.3.2011, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет



Блин, как красиво! Все - сажусь свой грабер переписывать.

Предлагаю опытным товарищам не оставлять данную граберно-парсерную тему, поскольку еще есть вопросы.

1. Многопоточность. 
infarch, многопоточность Вашего грабера была реализована на Perl? (вроде как глупо на perl форуме такое уточнять, но достаточно ли эта многопоточность в Perl стабильна? Много всякого разного читал, как то не особенно ее используют и мягко говоря недолюбливают) (а php работает с потоками?)
и кстати понятно, что для схемы infarch нужна работа БД, текстовые фалы не прокатят - а работает ли perl с DBF файлами? - mysql не всегда удобен ( в смысле быстрой переносимости) - а DBF файл самое то.

2. Что делать,  если ссылки меню  организованы Js скриптом
как вот например, в таком вот примере
http://cmec.spb.ru/dm/index/reestr

попросили сграбить, да не тут то было
Как правильно подойти к данному сайту - возможно ли сграбить его при помощи perl?

Спасибо





Это сообщение отредактировал(а) burakov - 31.3.2011, 08:30


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
infarch
Дата 31.3.2011, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



Вся многопоточность у меня сделана на threads, threads::shared, Thread::Queue, Thread::Semaphore. Этого вполне достаточно, работает на xp и seven без нареканий. Как там пхп - не знаю, не пользуюсь. И по DBF не скажу... а в чем проблема перенести базу мускуля? Дампом за 5 минут делается.

Ко второму вопросу: при помощи перл можно сделать все что делается на других языках. Где сложнее, где проще... Так что главное - голова а не язык реализации smile В вашем случае придется конечно попотеть, непростой сайт. И дело тут никак не в языке програмирования. Поставьте снифер и понаблюдайте какие запросы посылает скрипт, ваша задача - сделать аналогичные. Типа вот этого: http://cmec.spb.ru/dm/index/getbranch?oid=...47350.2021&. Он возвращает json, анализируйте, формируйте следующие запросы.

зы. с фри-ланс.ру проект? видел там такое, не взялся ввиду занятости smile
PM MAIL   Вверх
burakov
Дата 31.3.2011, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет



Спасибо за ответы.

По поводу mysql - хорошее дело не спорю и перенести легко и т.д. (но проекты то с фриланс smile - и это правда, поэтому - то просто отдал, а то приходится все это настраивать, кому под линукс, кому под windows и т.п. радмины и всяко прочее, путаница в кодировках)

По поводу снифера - это да, это конечно, но интересовало универсальное решение - в случае допустим изменения в меню

По поводу того что все можно сделать на perl - это да. Хотя вот с графикой в нем тяжело perl/tk такой уж некрасивый, может уже чего более универсальное красивое придумали?
И еще вот что в перл угнетает - много сейчас разных CMS, где используется PHP + jscript (MVC), ну и вообще PHP хорошо в HTML встраивается, везде поддерживается, а perl получается как то сбоку - вроде бы и язык помощнее, и можно его и так и эдак использовать, а приходится учить PHP. В php вроде как и графического интерфейса своего написать нельзя, но из-за связки html+php+jscript+mysql
все преимущества perl как то нивилируются...

И вот еще один вопрос.
Сейчас я следую такой схеме грабинга - Скрипт запускаю из консоли  (ну то есть получается локальное приложение запускается на машине подключенной к инету) - он все грабит парсит и дает на выходе или бд или файл структурированный,  и далее уже руками импорт в CMS на хостинге или еще куда, а как реализовать такую схему:

чтобы сайт (на хостинге) - сам себя наполнял, обновлял и т.п. - не могу понять возможно ли такое?
и как это реализовать? используя CGI Скрипт. (из учета, что на многих хостингах консоль недоступна)


--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
infarch
Дата 31.3.2011, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 526
Регистрация: 13.3.2009

Репутация: нет
Всего: 1



"сам себя наполнял, обновлял" - Оно конечно возможно, вот только гораздо сложнее. Рискуете столкнуться в один прекрасный день с тем что донор изменит структуру данных и автоматически похерится все что уже было закачано. Да и прочих деталей полно. И не всякий хостинг даст ssh и права на доустановку модулей. Я за такое не берусь, потом клиенты задолбают. Только сам граблю и переношу на движок клиента. Разве что особо проверенным товарищам можно сделать исключение ;) Можете заключить с клиентом договор на последующие апдейты за скромную плату, ведь все уже готово - только запускай скрипты и вперед.

Разве что вот такое разделение - грабить отдельно html и файлы. хтмл еще обрабатывать надо, а вот файлы только скачать. если вы их от себя скачате, потом придется перекачивать клиенту, а это лишняя работа. Лучше составить список закачки и примитивным скриптом выполнить это на клиенте.

Хотя дело вкуса, если мало файлов или супер хороший интернет то это не напрягает.
PM MAIL   Вверх
burakov
Дата 31.3.2011, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 554
Регистрация: 28.7.2006

Репутация: нет
Всего: нет



Спасибо, все понятно, 
Тему пока не стану закрывать (пишу грабер, может чего еще спрошу smile)




--------------------
Нотный архив http://libnote.ru скачать ноты бесплатно
PM MAIL   Вверх
shamber
Дата 31.3.2011, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1422
Регистрация: 5.9.2006
Где: Россия

Репутация: нет
Всего: 18



burakov, поищите, на форуме грабер пробегал.
PM MAIL Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl: CGI программирование"
korob2001
sharq
  • В этом разделе обсуждаются вопросы относящиеся только к CGI программированию
  • Если ваш вопрос не относится к системному или CGI программированию, задавайте его в общем разделе
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", качать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: разработка для Web | Следующая тема »


 




[ Время генерации скрипта: 0.0525 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.