$tag eq 'a' and $attr->{name} and do { my $name = $attr->{name}; $parser->{fragment}{$name} = 1; }; }
我们只是关心最基础的以及一个标签。如果我们发现一个基本的元素,我们保存超连接,因此,我们可以解析相关连接。当我们发现一个连接,我们创建一个新的URI对象,把它加到连接的列表中。最后,我们找到一个片断,把它加到片断的哈希列表中。 我们有两个访问器: $parser->links() 如果$fragment存在于这个页面,它返回true.
Page Page包得到和解析web页面。web页面是交互连接的。也许可能有很多相同连接都是指向同一个页面。然而,下载页面花费时间,因此,我们不想下载同一个页面多次。
Page把web页面缓存在%Page::Content中。URL是哈希的键,页面的内容是它的值。当我们第一次请求页面的时候,Page下载它,并将它放在缓存中。任何以下的相同请求都是从缓存中读取。
Page包还解析web页面。解析一个web页面,并不需要网络的I/O,但是这仍然花费时间,如果我们对每个片断都检查解析的话,时间也许就会用得很多。 为了避免这个,Page包缓存了解析后的内容在%Page::Parse中。哈希的键是URL,值是一个HTML::Parser::Links对象。
下面是一个外部的接口: $page = new Page $uri; $uri = $page->uri; 上一篇 目录 下一篇s = $page->links; $content = get $page; $parser = parse $page;
Link Link包检查一个连接的有效性。 它的外部接口非常简单: 上一篇 目录 下一篇 = new Link $uri; $ok = 上一篇 目录 下一篇->check; 和Page包一样,Link有许多对不必要的操作的优化。 检查连接分为两个部份。如果连接有碎片的话, http://my.isp.com/page.html#section 那么我们就必须下整个的页面。事实上,我们甚至不必下载它。一个头部请求就可以告诉我们这个页面是否存在,而这个就是我们所关心的。 在内部,check()方法分别调用check_fragment()或者check_base(),来处理这两个事件。check_fragment()使用Page包来下载,解析包,然后,它检查看是否碎片存在于这个页面。check_base()发出一个头部请求,直接看是否存在这个页面。 无论在哪个事件,check()缓存结果到%Link::Check。因此,我们可以不必对相同的连接检查两次。
Program 由于所有的基础都由包和模块提供了,我们可以在100行代码内完成linkcheck这个程序。下面是主程序: package main;
my %Options; my %Checked; my($Scheme, $Authority); my($Pages, $Links, $Broken) = (0, 0, 0);
getopt('vt', %Options); Help(); CheckPages(@ARGV); Summary();
Globals 我们声明我们的全局变量。这是我们的主程序。文档范围也许就属于这里。%Options保存了命令行的选项。%Checked 是一个已经检查过了的url的哈希结构。我们用它来避免由于循环连接而带来的无限的递归运算。$Authority报告当前的站点。我们用它来确定在站的连接。$Pages, $Links 和 $Broken保存Progress()和Summary()的计数。
CheckPages 当处理好了命令行的选项后,@ARGV就包含了要检查的网页的一个列表。 CheckPages()产生为每个网页产生一个URI的对象,并调用 CheckPage()。 sub CheckPages { my @pages = @_; my @URIs = map { new URI $_ } @pages;
for my $uri (@URIs) { $Scheme = $uri->scheme; $Authority = $uri->authority; CheckPage($uri); } }
CheckPage CheckPage()检查一个网页。 sub CheckPage { my $uri = shift;
$Checked{$uri} and return; $Checked{$uri} = 1; $Pages++; Twiddle(); print "PAGE $urin" if $Options{v} > 1;
my $page = new Page $uri; my 上一篇 目录 下一篇s = $page->links; defined 上一篇 目录 下一篇s or die "Can't get $urin";
CheckLinks($page, 上一篇 目录 下一篇s); }
经过一些内部管理后,它产生一个新的Page对象,得到在这个网页上的所有的连接,然后调用CheckLinks()。 linkcheck检查坏的连接,但是用户所指定的那些必须存在。如果我们不能下载其中的一个,我们就停止。
CheckLinks CheckLinks()检查在一个页面上的连接。 sub CheckLinks { my($page, 上一篇
如果您对本文有任何疑问或者建议,请到讨论区发表您的意见:
>>
论坛入口 <<
上一页 1 2 34 下一页
上一篇:联网调试CGI程序心得 下一篇:Perl的运算符号字符概述
|