获取页面[LWP]解析它们[HTML :: TokeParser]并存储结果[DBI]

时间:2010-10-16 21:23:14

标签: html-parsing store lwp

三重工作:我必须完成树任务。我们有三个任务:

  1. 抓取页面
  2. 解析HTML
  3. 存储数据......是的 - 这是一个真正的Perl工作!
  4. 我必须在瑞士的一个网站的所有6000个子页面上做一个解析器工作。 (政府网站 - 拥有非常好的服务器)。

    请参阅http://www.educa.ch/dyn/79362.asp?action=search
    (如果您没有看到大约6000个结果 - 那么请使用进行搜索。

    详细页面是这样的:

    [link text] [1]

    • Ecole nouvelle de la Suisse Romande CH。 deRovéréaz20邮件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. 存储数据
    4. 第一项:使用LWP :: UserAgent进行提取。此论坛中有许多使用该模块发布数据并获取结果页面的示例。顺便说一句,如果我们愿意,我们可以使用Mechanize。

      第二:解析页面,例如使用HTML :: TokeParser或其他模块来获取我们需要的数据。

      第三:将数据直接存储到数据库中。无需采取中间步骤并编写临时文件。

      嗯 - 第一个和第二个问题 - 如何获取以及如何解析。

1 个答案:

答案 0 :(得分:2)

很难过于具体,因为你的问题非常笼统。我使用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元素都会传递给一个数组,您可以检查该数组以确定接下来应该做什么。

在上面的示例中,我想搜索属性名称为“SEARCHVALUE”的输入标记,然后存储“value”属性。 HTML片段可能如下所示:

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

当我点击输入标签的开头($ t-&gt; [0] eq'S'和$ t-&gt; [1] eq'input')我检查标签的“name”属性( t-&gt; [2] {'name'})查看它是否与我正在搜索的值相匹配;如果是的话,我将标签的值属性($ t-&gt; [2] {'value'})存储在变量中。然后,我可以随心所欲地做任何我喜欢的事情,包括将其存储在数据库中。

你可以使用TokeParser做很多事情,在某些情况下,它可以比使用正则表达式来分割页面更简单,但它也可能有点难以理解。如果您尝试从返回HTML内容中提取简单模式,那么正则表达式就可以了。

如果您有很多这方面的事情,那么我推荐来自O'Reilly的Sean Burke的“Perl和LWP”。在我的网络搜索工作中,它对我无休止的帮助。

希望这有助于您至少开始。