Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > программа "умирает"


Автор: DEER 20.3.2006, 17:02
привет всем
http://forum.vingrad.ru/index.php?showtopic=87856 я спрашивал , про закачку картинок, всё понял,
написал программку, суть её в следующем.

она заходит на страницу, ищет на ней список ссылок, этот список в массив $list_url{$deskription}=$url.

далее идёт цикл, просматриваются все элементы массива(хеша),
печатается описание к ссылке;
для каждого элемента вызывается следующий алоритм:
- получаем страницу по ссылке;
- там ищем ещё один список со ссылками;
- заходим по каждой ссылке, берём от туда картинку
- печатаем новый адрес картинки

в конце концов должно получится примерно следующее
Цитата

категория1
  1.jpg
  2.ipg
категория2
  3.jpg
категория3
  4.jpg
  5.jpg
  6.jpg

...и так далее до конца хеша %list_url


вроде всё работает.
но на практике, ссылок оказалось очень много, и ещё я поставил перед каждым запросом sleep(2), чтобы не нагружала сервак, откуда качаю. Время работы программы должно быть примерно часа 4(это я оценив, скока он скачал за 10 минут прикинул).
Через час работы программы, получается следующий список
Цитата

категория1
  1.jpg
  2.ipg
категория2
  3.jpg
категория3
категория4
категория5
категория6
...и так далее до конца хеша %list_url

т.е. программа, не заходит в процедуру получения картинок, а просто печатает хеш до конца и выключается.

Так вот вопрос: из за чего это может быть?
проблема в серваке? может там стоит какая нить константа, показывающая сколько максимально по впемени может работать скрипт?
или проблемма в программе? или может я сильно часто делаю запросы на страницу?
Щас ещё одна мысль пришла... а может это админ того сайта, откуда я картинки беру отрубил моё соединение?



Автор: nitr 20.3.2006, 17:20
Покажи немного кода smile где у тебя со слипами

Автор: DEER 20.3.2006, 17:38
ну например вот:
Код

#закачивает картинку
sub get_pict
{
    my $art = shift; # имя картинки
    my $res;
    my $numer = shift;  # kjrfkmyjt bvz rfhnbyrb
    my $ua = LWP::UserAgent->new();
    $ua->timeout(5);
    $ua->agent( "Mozilla/5.0" );
        my $url = "$server/photo/$art.jpg";
        sleep(2);
        my $document = $ua->request( HTTP::Request->new( GET => $url ) );
    my $tmp = $document->content;
    if(($tmp=~/<html>/i)||($tmp=~/<HTML>/))  # если вернулясь не страница ошибки веб-сервера
    {
     $res = "";
    }
    else # то это картинка
    {
        open( FILE, ">$numer.jpg" );
        binmode( FILE );
        print FILE $tmp;
        close( FILE );
        $res = "$numer.jpg";
    }
    return $res;
}
#находит на странице список ссылок
sub get_child_categories
{
    my $url = shift; # урл станицы
    my %res = qw();
    my $ua = LWP::UserAgent->new();
    $ua->timeout(5);
    $ua->agent( "Mozilla/5.0" );
        sleep(2);
    my $document = $ua->request( HTTP::Request->new( GET => $url ) );
    my $the_dump = $document->content;
    $the_dump=~s/\n/ /g;
         # если есть участок кода, то берём из него данные и засовываем в хеш
    while($the_dump=~/<TD\s+width=\"350\"\s+valign=\"middle\"\s+height=\"18\"\s+colspan=2><A\s+href=\"\.(\/index.php\?menu_id=\d*\&step=\d*&type_id=\d*\&subtype_id=\d*)\">([^<]*)/g)
    {
        $res{$server.$1} = $2;
    }
    return %res;
}


сначала вызывается get_child_categories, потм для каждого элемента, еще одна функция get_list, почти аналогичная get_child_categories (только регулярное выражение другое),
потом, вызывается фуекция get_pict, для того что нашла get_list.
Добавлено @ 17:41
ещё.
код рабочий, потому что перед тем как умереть, он успевает собрать около 900 картинок

Автор: nitr 20.3.2006, 17:51
Первое на что могу подумать это ПЛОХОЙ КОННЕКТ smile у тебя стоит $ua->timeout(5); smile Либо увеличивай, либо создай проверочную процедуру на хороший коннект к серваку откуда качаешь ссылки!
Добавлено @ 17:54
Ещё... при использовании прокси НЕОБХОДИМА такая процедура! (проверка на "быстрый" коннект или доступность). Используй стандартные сокеты, либо тот же LWP, возьми почитай про ошибки типа 500, 200 OK и т.д. smile Очень поможет в будущем. Модуль не посоветую, т.к. сам такие не встречал smile

Автор: DEER 20.3.2006, 18:01
а что есть $ua->timeout(5);

?
это он будет 5 секунд ждать до ответа, а потом если его нет, то не ждёт больше?
Добавлено @ 18:02
спасибо, буду копать

Автор: nitr 20.3.2006, 18:44
=) Это значит что ждать всего 5 секунд и дисконнект smile , чтобы не висеть smile По умолчанию 30. Лучше создай процедурку примерно так smile

Код

sub check_proxy
{
  my ($host, $port) = @_;
  $ch_proxy = IO::Socket::INET->new(PeerAddr=> $host, PeerPort=> $port, TimeOut => 10);
  return 0 unless $ch_proxy;
  $ch_proxy->close;
  return 1;
}

Автор: sharq 21.3.2006, 12:44
DEER, sleep вообще убери и попробуй вести лог:

Код

open STDERR, '>', 'myerr.log';

...

warn "Get page $url \n";

...

warn "Get image $image\n";




И отследить, где ошибка!

Попробуй fork для ускорения закачки! Я здесь приводил свой пример закачки страницы через прокси, можешь поискать!


smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)