извлекать страницы [LWP], анализировать их [HTML :: TokeParser] и сохранять результаты [DBI] - PullRequest
1 голос
/ 17 октября 2010

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

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

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

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

A подробная страница выглядит так:

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

  • Новая школа искусств в Риме Глава de Rovéréaz 20 Дело почтовое 161 1000 Лозанна 12 Веб-сайт info@ensr.ch Тел: 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: schorderet@inbox.lv">schorderet@inbox.lv</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 или другого модуля, чтобы получить только те данные, которые нам нужны.

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

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

1 Ответ

2 голосов
/ 22 октября 2010

Трудно быть слишком конкретным, так как ваш вопрос очень общий. Я извлек страницы с помощью LWP и использовал TokeParser для извлечения данных и много раз сохранял вывод в базе данных. Я не использовал мех, но по всем показателям он проще, чем 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 передается в массив, который вы можете проверить, чтобы определить, что делать дальше.

В приведенном выше примере я хочу найти входные теги с именем атрибута 'SEARCHVALUE', а затем сохранить атрибут 'value'. Фрагмент HTML может выглядеть примерно так:

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

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

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

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

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

...