1

三重工作:我必须完成一项与树任务有关的工作。我们有三个任务:

  1. 获取页面
  2. 解析 HTML
  3. 存储数据...是的 - 这是一个真正的 Perl 工作!

我必须对瑞士网站的所有 6000 个子页面进行解析器工作。(一个政府网站 - 有非常好的服务器)。

请参阅 http://www.educa.ch/dyn/79362.asp?action=search
(如果您没有看到大约 6000 个结果- 然后使用.

详细的页面是这样的:

[链接文字][1]

  • Ecole nouvelle de la Suisse Romande Ch. de Rovéréaz 20 Case postal 161 1000 Lausanne 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 获取。这个论坛中有很多使用该模块发布数据并获取结果页面的示例。顺便说一句,如果我们愿意,我们可以使用机械化。

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

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

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

4

1 回答 1

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 token 遍历流。每个 HTML 元素都被传递到一个数组中,您可以检查该数组以确定下一步应该做什么。

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

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

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

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

如果你有很多事情要做,那么我推荐来自 O'Reilly 的 Sean Burke 的“Perl and LWP”。在我的网络抓取工作中,它对我有无穷无尽的帮助。

希望这至少可以帮助您入门。

于 2010-10-22T00:03:41.487 回答