LINUX.ORG.RU

[PERL] Глубина рекурсии

 


0

0

Здравствуйте, я Кирилл.

Ковыряю perl-скрипт, производящий рекурсивную закачку некой страницы. С радостью бы использовал wget, но там вместо человеческих ссылок - пустышки, с подвешенными на onclick javascript функциями, которые в div закачивают некий html-код. AJAX типа. Получается такое деревце. Отследив передаваемые заголовки - выделил url странц, отдающих контент в DIVы, а дальше - дело техники.

1  #!/usr/bin/perl -w
2  use GovnoWget;
3  use strict;
4  
5  my $start_link      = "http://...";
6  my $cache_dir       = "govno_wget_cache";
7  
8  # 1 этап. Получаем контент страниц и сохраняем в кэше
9  page_download($start_link, 0);
10 # 2 это
11 
12 # Загрузка страницы со следованием по AJAX-ссылкам
13 sub page_download {
14     my ($url, $deep) = @_;
15 
16     # Увеличиваем счетчик глубины рекурсятины
17     $deep++;
18
19     # Закачиваем страничку с сохранением её в каталоге кэша
20     my $html = GovnoWget::http_get({url => $url, cache_dir => $cache_dir});
21     # Получаем список элементов-ссылок на этой странице для дальнейшей загрузки
22     my @page_items = page_parse_urls($html);
23     # Грузим каждую из страниц
24     page_download($_, $deep) foreach @page_items;
25     # Выводим url загружаемой страниы и глубину "погружения"
26     print $_."\t\t{deep $deep}[OK]"."\n" foreach @page_items;
27 }
28
29 # Парсим html-страницу, получая из AJAX-ссылок нормальные ссылки для загрузки
30 sub page_parse_urls {
31     my ($html) = @_;
32     my @items = ();
33     push (@items, "http://.../$1")
           while $html =~s/open_thread\(\s*[\"\']{0,1}c(\d+?)[\"\']{0,1}\s*\)
34         .*?>(.*?)<//xm;
35     return @items;
36 }

Скрипт работает, и успевает награбить 2760 корованов

$ ls -lah govno_wget_cache/|wc -l
2760

Однако в определённый момент срубается вот с таким сообщением

http://.../10156         {deep 5}[OK]
http://.../10164         {deep 5}[OK]
http://.../10179         {deep 7}[OK]
http://.../10177         {deep 6}[OK]
http://.../10187         {deep 7}[OK]
http://.../10185         {deep 6}[OK]
http://.../10175         {deep 5}[OK]
http://.../10183         {deep 5}[OK]
http://.../10151         {deep 4}[OK]
http://.../10155         {deep 4}[OK]
http://.../10173         {deep 4}[OK]
http://.../10193         {deep 4}[OK]
http://.../9924          {deep 3}[OK]
http://.../9939          {deep 3}[OK]
http://.../9954          {deep 3}[OK]
http://.../10021         {deep 3}[OK]
http://.../10101         {deep 3}[OK]
http://.../10107         {deep 3}[OK]
http://.../10115         {deep 3}[OK]
http://.../10126         {deep 3}[OK]
http://.../10138         {deep 3}[OK]
http://.../10142         {deep 3}[OK]
http://.../10150         {deep 3}[OK]
http://.../10192         {deep 3}[OK]
http://.../10199         {deep 3}[OK]
http://.../10202         {deep 3}[OK]
http://.../10208         {deep 3}[OK]
http://.../10213         {deep 3}[OK]
Deep recursion on subroutine "main::page_download" at ./myscript.pl line 24.

Как быть? :-(

★☆☆

Вопрос решен контролем переменной $deep (не более 30), но осадок остался.

r_asian ★☆☆
() автор топика

ну, можно и без рекурсии обойтись. как-то так:

my @urls = ($start_url);
while (@urls) {
    my $html = …::http_get({url=>shift(@urls), …});
    push @urls, page_parse_urls($html);
}

arsi ★★★★★
()
Ответ на: комментарий от arsi

> ну, можно и без рекурсии обойтись
Ох нет, это же некошерно!

anonymous
()

насколько я знаю -- это просто ворнинг, который перл выдает если глуюина рекурсии превышает некую константу (вроде 100 по дефолту). Это не жесткий лимит.

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.