Отправляет email-рассылки с помощью сервиса Sendsay

Perl - подпишись и учись!

  Все выпуски  

PERL и LWP


Информационный Канал Subscribe.Ru


 Hi, All!  
    Приветствую всех!(А именно 8331 подписчиков)

Рад Вас приветствовать!
Сегодня рассылка будет посвящена модулю LWP.
Cтатья, которую Вы, надеюсь, видите ниже, является первой частью перевода статьи, размещённой по адресу: http://www.perl.com/pub/a/2002/08/20/perlandlwp.html.
Через некоторое время, я разошлю и вторую половину этой статьи, так что ждите.
Статья в основном, я думаю, будет полезна новичкам. Она даёт некоторое представление о модуле LWP и показывает, как им пользоваться. Итак, дерзайте...

Web Основы с LWP

Автор: Sean M. Burke
Перевод: Дмитрий Николаев
Август 20, 2002

Введение

LWP (сокращение от "Library for WWW in Perl") это очень популярная группа модулей языка Perl для доступа к данным в сети Internet. Как и большинство модулей языка Perl, на каждый модуль из состава LWP присутствует документация с полным описанием его интерфейса. Однако, в LWP есть множество модулей, для которых довольно сложно найти документацию по, казалось бы, простейшим вещам.

Введение в использование LWP, очевидно, должно занять целую книгу, -- книгу, которая только вышла из печати, и названную: Perl & LWP. Эта статья предлагает Вам несколько примеров, которые помогут Вам в организации обычных вещей с LWP.

Доступ к страничкам с помощью LWP::Simple

Если Вы всего лишь хотите получить документ, находящийся по определённому адресу(URL), то самый простой способ сделать это - использовать функции модуля LWP::Simple.


Perl & LWP

Книга по теме

Perl & LWP
Автор: Sean M. Burke


В Perl-скрипте Вы можете сделать это, вызвав функцию get($url). Она попытается вытянуть содержимое этого URL. Если всё отработает нормально, то функция вернёт это содержимое; но если произойдёт какая-нибудь ошибка, то она вернёт undef.


  my $url = 'http://freshair.npr.org/dayFA.cfm?todayDate=current';
  # Всего лишь для примера: новые записи на /Fresh Air/

  use LWP::Simple;
  my $content = get $url;
  die "Couldn't get $url" unless defined $content;

  # Далее что-нибудь делаем с $content, например:

  if($content =~ m/jazz/i) {
    print "They're talking about jazz today on Fresh Air!\n";
  } else {
    print "Fresh Air is apparently jazzless today.\n";
  }

Более удобный вариант функции get - это getprint,
opros.alkar.net
который удобен для простмотра содаржимого страниц через Perl. Если функция getprint может "достать" страничку, адрес которой Вы задали, то она отправляет содержимое в STDOUT; в противном случае, в роли жалобной книги выступает STDERR.


  % perl -MLWP::Simple -e "getprint 'http://cpan.org/RECENT'"

Это URL простого текстового файла. В нём содержится список новых файлов на CPAN за последние две недели. Вы легко можете сделать shell-команду, которая, например, будет высылать Вам список новых модулей Acme:::


  % perl -MLWP::Simple -e "getprint 'http://cpan.org/RECENT'"  \
     | grep "/by-module/Acme" | mail -s "New Acme modules! Joy!" $USER

В модуле LWP::Simple существует ещё несколько довольно полезных функций, включая функцию для выполнения HEAD-запроса для URL (полезна для проверки ссылок или получения даты последней корректировки документа) и две функции для сохранения и зеркалирования URL в локальный файл. Смотрите документацию по LWP::Simple для более детальной информации, или Главу 2, "Web Основ" Perl & LWP для большего количества примеров.

Основы классовой модели LWP

Функции LWP::Simple удобны только для простых случаев, но эти функции не поддерживают теневых посылок(далее cookies) и проверки подлинности(далее authorization); Они также не позволяют устанавливать какие-либо параметры HTTP запроса; и главное, они не позволяют считывать строки заголовка в HTTP ответе (особенно полный текст сообщения в случае HTTP ошибки( HTTP error message)). Для доступа ко всем этим возможностям, Вы должны использовать весь набор классов LWP.

LWP содержит множество классов, но главные два, которые Вы должны понимать - это LWP::UserAgent и HTTP::Response. LWP::UserAgent это класс для "виртуальных броузеров", кторыми Вы будете пользоваться для выполнения запросов. HTTP::Response это класс для ответов (или сообщений об ошибке), которые Вы получаете обратно, после запроса.

Основное выражение при работе с LWP: $response = $browser->get($url), или полностью:



  use LWP 5.64; # Загружаем все нужные LWP классы, и удостовериваемся
                # в достаточной свежести версии модуля.

  my $browser = LWP::UserAgent->new;

  ...

  # Используется ниже, тот URL, которому и будет сделан запрос:
  my $url = 'http://freshair.npr.org/dayFA.cfm?todayDate=current';

  my $response = $browser->get( $url );
  die "Can't get $url -- ", $response->status_line
   unless $response->is_success;

  die "Hey, I was expecting HTML, not ", $response->content_type
   unless $response->content_type eq 'text/html';
     # или другой content-type, который Вам подходит

  # В противном случае, производим обработку содержимого:

  if($response->content =~ m/jazz/i) {
    print "They're talking about jazz today on Fresh Air!\n";
  } else {
    print "Fresh Air is apparently jazzless today.\n";
  }
В этом примере было включено два объекта, в сравнении с предыдущим примером: $browser, который содержит объект класса LWP::UserAgent, и объект $response, который из класса HTTP::Response. Обычно Вам надо не более одного объекта $browser; но каждый раз как Вы делаете запрос, Вы получаете назад новый объект HTTP::Response, который содержит несколько интересных методов:
  • Status code(Код состояния), который показывает успех либо неудачу запроса (Вы это можете проверить так: $response->is_success).

  • HTTP status line(строка состояния), которая, я думаю, будет довольна информативна в случае ошибки (её Вы можете увидеть, используя $response->status_line, она возвращает что-то вроде: "404 Not Found").

  • MIME content-type, например "text/html", "image/gif", "application/xml", и т.д., который Вы можете увидеть, используя $response->content_type

  • Собственно содержимое запрашиваемого документа в $response->content. В случае с HTML, здесь будет HTML код; если - GIF, то $response->content вернёт бинарные данные GIF.

  • А также множество удобных и более специфических, которые описаны в документации по HTTP::Response, и его суперклассам, HTTP::Message и HTTP::Headers.

Добавление других заголовков HTTP запроса

Вот наиболее часто используемый синтаксис для запросов $response = $browser->get($url), но, честно говоря, Вы можете добавлять собственные строки HTTP заголовков к запросу, добавлением списка пар ключ-значение после URL, например:


  $response = $browser->get( $url, $key1, $value1, $key2, $value2, ... );

Вот как отправить Netscape-подобные заголовки:


  my @ns_headers = (
   'User-Agent' => 'Mozilla/4.76 [en] (Win98; U)',
   'Accept' => 'image/gif, image/x-xbitmap, image/jpeg,
        image/pjpeg, image/png, */*',
   'Accept-Charset' => 'iso-8859-1,*,utf-8',
   'Accept-Language' => 'en-US',
  );

  ...

  $response = $browser->get($url, @ns_headers);

Если Вы не будете использовать этот массив в дальнейшем, Вы можете поступить следующим образом:



  $response = $browser->get($url,
   'User-Agent' => 'Mozilla/4.76 [en] (Win98; U)',
   'Accept' => 'image/gif, image/x-xbitmap, image/jpeg,
        image/pjpeg, image/png, */*',
   'Accept-Charset' => 'iso-8859-1,*,utf-8',
   'Accept-Language' => 'en-US',
  );

Если Вы собираетесь изменить только 'User-Agent'-параметры, Вы можете изменить стандартную установку объекта $browser "libwww-perl/5.65" (или что-то подобное) на всё что Вы хотите, используя соответствующий метод объекта LWP::UserAgent:


   $browser->agent('Mozilla/4.76 [en] (Win98; U)');

Включение Cookies(Теневых посылок)

Обычно объект LWP::UserAgent работает как броузер с отключённой поддержкой cookies. Существует несколько путей для того, чтобы включить такую поддержку, используя метод cookie_jar. "cookie jar" - это объект, который, если можно так сказать, олицетворяет собой маленькую БД со всеми HTTP cookies, о которых может знать броузер. "БД" может быть сохранена на диск (так работает Netscape, используя файл cookies.txt), или "висеть" в памяти, при этом весь набор cookies будет потерян, как только программа завершит свою работу.

Для того, чтобы создать пустой объект cookie jar в памяти, вызовите cookie_jar метод следующим образом:


  $browser->cookie_jar({});

Для того, чтобы делать копии cookies в файл на диске, который будет содержать весь набор cookies, с которыми работал броузер, после завершения программы, вызовите cookie_jar метод следующим образом:


  use HTTP::Cookies;
  $browser->cookie_jar( HTTP::Cookies->new(
    'file' => '/some/where/cookies.lwp',
        #файл обмена
    'autosave' => 1,
        #по завершении, сохранять ли файл
  ));

Этот файл будет в специфическом формате LWP. Если Вы хотите получить доступ к cookies из вашего Netscape-cookies файла, Вы можете использовать следующий метод: HTTP::Cookies::Netscape:


  use HTTP::Cookies;

  $browser->cookie_jar( HTTP::Cookies::Netscape->new(
    'file' => 'c:/Program Files/Netscape/Users/DIR-NAME-HERE/cookies.txt',
        # откуда читать куки
  ));

Вы можете добавить строку 'autosave' => 1 , как мы делали ранее, но в момент записи существует вероятность того, что Netscape может отказать в записи некоторых cookies обратно на диск.

Отправка данных форм методом POST

Многие HTML формы отправляют данные на сервер, используя запрос HTTP POST, который вы можете осуществить следующим образом:


 $response = $browser->post( $url,
   [
     formkey1 => value1,
     formkey2 => value2,
     ...
   ],
 );
Или, если Вам нужно посылать HTTP заголовки:

 $response = $browser->post( $url,
   [
     formkey1 => value1,
     formkey2 => value2,
     ...
   ],
   headerkey1 => value1,
   headerkey2 => value2,
 );

Например, следующая программа осуществляет поисковый запрос на AltaVista (отправкой некоторых данных форм, используя метод HTTP POST), и извлекает из теста ответа количество совпадений:


  use strict;
  use warnings;
  use LWP 5.64;
  my $browser = LWP::UserAgent->new;

  my $word = 'tarragon';

  my $url = 'http://www.altavista.com/sites/search/web';
  my $response = $browser->post( $url,
    [ 'q' => $word,  #поисковая фраза
      'pg' => 'q', 'avkw' => 'tgz', 'kl' => 'XX',
    ]
  );
  die "$url error: ", $response->status_line
   unless $response->is_success;
  die "Weird content type at $url -- ", $response->content_type
   unless $response->content_type eq 'text/html';

  if( $response->content =~ m{AltaVista found ([0-9,]+) results} ) {
    #Подстрока будет вида: "AltaVista found 2,345 results"
    print "$word: $1\n";
  } else {
    print "Couldn't find the match-string in the response\n";
  }

Передача данных форм методом GET

Некоторые HTML формы передают данные не отправкой методом POST, а совершением обыкновенного GET запроса с определённым набором данных в конце URL. Например, если Вы пойдёте на imdb.com и запустите поиск по фразе Blade Runner, то URL, который Вы увидите, будет следующим:


  http://us.imdb.com/Tsearch?title=Blade%20Runner&restrict=Movies+and+TV

Для запуска такого поиска при помощи LWP, надо сделать следующее:


  use URI;
  my $url = URI->new( 'http://us.imdb.com/Tsearch' );
    # создаёт объект, представляющий URL

  $url->query_form(  # Здесь пары ключ => значение:
    'title'    => 'Blade Runner',
    'restrict' => 'Movies and TV',
  );

  my $response = $browser->get($url);

Смотрите Главу 2, "Формы" книги Perl & LWP для более подробного изучения HTML форм, также как и главы с шестой по девятую для подробного изучения извлечения данных из HTML.



to be continued....:)

Советую описание модуля на русском, которое Вы можете найти по адресу: http://perl.dp.ua/perlevods

________________________________________
И ещё, если у вас есть вопросы, то задавайте их на форуме сайта(http://perl.dp.ua).
________________________________________

                С уважением, Дмитрий.



Another Banner Network

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное