извлекать страницы [LWP] анализировать их [HTML::TokeParser] и сохранять результаты [DBI]

Тройное задание: мне нужно выполнить задание с деревом. У нас есть три задачи:

  1. Получить страницы
  2. Разобрать HTML
  3. Хранить данные... И да, это настоящая Perl-работа!

Мне нужно выполнить синтаксический анализ всех 6000 подстраниц сайта в suisse. (правительственный сайт с очень хорошими серверами).

см. http://www.educa.ch/dyn/79362.asp?action=search и
(если вы не видите около 6000 результатов, выполните поиск с помощью .

Подробная страница выглядит следующим образом:

[текст ссылки][1]

  • Ecole nouvelle de la Suisse Romande Ch. de Roveréaz 20 Case postal 161 1000 Lausanne 12 Веб-сайт [email protected] Тел: 021 654 65 00 Факс: 021 654 65 05

другие подробные страницы показывают это:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta name="generator" content="DigiOnline GmbH - WebWeaver 3.4 CMS - "><title>educa.ch</title><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><link rel="stylesheet" href="101.htm"><script src="102.htm"></script><script language="JavaScript"><!--
var did='d79376';
var root=new Array('d200','d205','d73137','d1566','d79376','d');
var usefocus = 1;
function check() {
if ((self.focus) && (usefocus)) {
self.focus();
}
}
// --></script></head><body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" onload="check();"><table cellspacing="0" cellpadding="0" border="0" width="100%"><tr><td width="15" class="popuphead"><img src="/0.gif" alt="" width="15" height="16"></td><td width="99%" class="popuphead">Adresse - Schulen in der Schweiz</td><td width="20" class="popuphead" valign="middle"><a href="#" title="Print" onclick="window.print(); return false;"><img src="../pics/print16x13.gif" alt="Drucken" width="16" height="13"></a></td><td width="20" class="popuphead" valign="middle"><a href="#" title="close" onclick="window.close(); return false;"><img src="../pics/close21x13.gif" alt="Schliessen" width="21" height="13"></a></td></tr><tr bgcolor="#B2B2B2"><td colspan="4"><img src="/0.gif" alt="" width="1" height="1"></td></tr></table><div class="leerzeile">&#160;</div><div class="leerzeile"><img src="/0.gif" alt="" width="15" height="8">Auseklis - Schule für lettische Sprache und Kultur</div><div class="leerzeile">&#160;</div><div><img src="/0.gif" alt="" width="15" height="8">Mutschellenstrasse 37</div><div><img src="/0.gif" alt="" width="15" height="8"></div><div><img src="/0.gif" alt="" width="15" height="8">8002&#160;Zürich</div><div class="leerzeile">&#160;</div><div><img src="/0.gif" alt="" width="15" height="8"><a href="http://latvia.yourworld.ch" target="_blank">latvia.yourworld.ch</a></div><div><img src="/0.gif" alt="" width="15" height="8"><a href="mailto: [email protected]">[email protected]</a></div><div class="leerzeile">&#160;</div><div><img src="/0.gif" alt="" width="15" height="8">Tel:<img src="/0.gif" alt="" width="6" height="8">+41786488637</div><div><img src="/0.gif" alt="" width="15" height="8">Fax:<img src="/0.gif" alt="" width="4" height="8"></div><div>&#160;</div></body></html>

Я хочу выполнить эту работу с помощью ** HTML::TokeParser или HTML::TokeParser** или *HTML::TreeBuilder::LibXML *, но у меня мало опыта работы с HTML::TreeBuilder::LibXML

Какой из них вы бы предпочли для этой работы: Примечание. Я хочу сохранить результаты в MySQL-DB. Лучше всего было бы сохранить его сразу после синтаксического анализа:

поэтому у нас есть три задачи:

  1. Получить страницы
  2. Разобрать HTML
  3. Хранить данные

Первый элемент: используйте LWP::UserAgent для получения. На этом форуме есть много примеров использования этого модуля для публикации данных и получения результирующих страниц. Кстати, мы можем использовать Mechanize, если захотим.

Второй: проанализируйте страницу, например, с помощью HTML::TokeParser или другого модуля, чтобы получить только те данные, которые нам нужны.

Третье: сохраняйте данные сразу в базе данных. Нет необходимости делать промежуточный шаг и писать временный файл.

хммм - первый и второй вопрос - как получить и как разобрать.


person zero    schedule 16.10.2010    source источник


Ответы (1)


Трудно быть слишком конкретным, так как ваш вопрос очень общий. Я извлекал страницы с помощью LWP и много раз использовал TokeParser для извлечения данных и сохранения вывода в базе данных. Я не использовал Mech, но по всем параметрам он проще, чем LWP.

Создание пользовательского агента с использованием LWP может быть таким простым, как:

my $ua = LWP::UserAgent->new();

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

Чтобы следовать перенаправлениям:

$ua = LWP::UserAgent->new(
    requests_redirectable =>   ['GET', 'HEAD', 'POST' ]
);

Чтобы сохранить файлы cookie:

$ua->cookie_jar( {} );

Чтобы настроить прокси:

$ua->proxy("http", "http://localhost:8888");  # Fiddler

Чтобы добавить пароль для аутентификации:

$ua->credentials( 'www.myhostingplace.com:443' , 'Realm' , 'userid', 'password');

Чтобы получить контент со страницы для локальной обработки:

$url = 'http://www.someurl.com'
my $response  = $ua->get($url);
if ( $response->is_error() ) {
   # Do some error stuff
}
my $content = $response->content();

Чтобы разобрать содержимое с помощью TokeParser:

my $stream = new HTML::TokeParser(\$content);

while ( my $t = $stream->get_token() ) {
   if ( $t->[0] eq 'S' and $t->[1] eq 'input' ) {
      if ( uc( $t->[2]{ 'name' } ) eq 'SEARCHVALUE' ) {
           my $data = $t->[2]{ 'value' };
           # Do something with data
      }
   }
}

Данные передаются в TokeParser как ссылка; Затем я прохожу через поток, используя токен get. Каждый элемент HTML передается в массив, который вы можете изучить, чтобы определить, что делать дальше.

В приведенном выше примере я хочу найти входные теги с именем атрибута «ЗНАЧЕНИЕ ПОИСКА», а затем сохранить атрибут «значение». Фрагмент HTML может выглядеть примерно так:

<input type="hidden" name="SEARCHVALUE" value="Spock" />

Когда я нажимаю начало входного тега ($t->[0] eq 'S' и $t->[1] eq 'input'), я проверяю атрибут «имя» тега (t->[2 ]{ 'имя' }), чтобы узнать, соответствует ли оно искомому значению; если это так, я сохраняю атрибут значения тега ($t->[2]{ 'value' }) в переменной. Затем я могу делать со значением все, что захочу, включая сохранение его в базе данных.

Вы можете многое сделать с помощью TokeParser, и в некоторых случаях это может быть проще, чем использование регулярных выражений для разделения страницы, но также может быть немного сложно разобраться. Если вы пытаетесь извлечь простой шаблон из возвращаемого HTML-содержимого, регулярное выражение может быть таким же хорошим.

Если у вас много работы, я рекомендую "Perl and LWP" Шона Берка из O'Reilly. Это было бесконечно полезно для меня в моих усилиях по очистке веб-страниц.

Надеюсь, это поможет вам хотя бы начать.

person Auctionitis    schedule 22.10.2010
comment
Здравствуйте Auctionitis, Большое спасибо за ответ. Это помогает мне начать. И да: я уже заказал книгу Perl и LWP Шона Бёрка. Отличный типп! Обратите внимание - у меня много дел. - я придумаю еще вопросы и прочее - но сейчас я сначала сделаю несколько упражнений. До скорого! С Уважением - person zero; 23.10.2010
comment
привет Auctionitis - еще раз спасибо за сообщение и ваши большие подсказки. кстати - я приложил еще несколько усилий - не могли бы вы помочь мне отладить. Рад услышать от вас - см. код для отладки! stackoverflow.com/questions/4007480/ - рад услышать от вас. Мартин - person zero; 25.10.2010