我正在做一个项目,把这里发现的每一个采访都放到一个HTML准备好的文档中,然后转储到数据库中,数据库将自动更新我们的网站和最新的内容。你可以看到我当前网站抓取脚本的一个例子,前几天我问了一个问题:WWW::Mechanize Extraction Help - PERL
我无法理解的问题是,我不知道我现在想要完成的事情是否有可能。因为我不想在新的采访发布时不得不猜测,所以我希望能够抓取包含所有采访目录列表的网站,并自动让我的程序获取新URL(新采访)上的内容。同样,有问题的网站在这里(向下滚动查看面试列表):http://millercenter.org/president/clinton/oralhistory
我最初的想法是在上面链接的末尾有一个。的正则表达式,希望它能自动搜索在该页下找到的任何链接。然而,我似乎无法使用WWW::Mechanize来实现这一点。我将张贴我在下面,如果有人有任何指导或经验与此您的反馈将非常感激。我还将在代码下面总结我的任务,以便您对我们希望完成的任务有一个简明的理解。
感谢所有能帮助我的人!
#!/usr/bin/perl -w
use strict;
use WWW::Mechanize;
use WWW::Mechanize::Link;
use WWW::Mechanize::TreeBuilder;
my $mech = WWW::Mechanize->new();
WWW::Mechanize::TreeBuilder->meta->apply($mech);
$mech->get("http://millercenter.org/president/clinton/oralhistory/.");
# find all <dl> tags
my @list = $mech->find('dl');
foreach ( @list ) {
print $_->as_HTML();
}
# # find all links
# my @links = $mech->links();
# foreach my $link (@links) {
# print "$link->url n";
# }
总结一下我希望什么是可能的:
像我在这里做的那样,在HTML准备好的文档中提取每个采访的内容:WWW::Mechanize Extraction Help - PERL。这将要求"get"动作能够遍历/oralhistory/目录下列出的页面,这可能可以使用正则表达式来解决。
可能在目录页上提取被调查者的姓名和位置字段,以便在标题字段中填充(如果不能这样做的话,这没什么大不了的)
不,你不能在url上使用通配符。: - (
您必须自己用清单解析页面,然后在循环中获取和处理页面。使用WWW::Mechanize…
从页面内容中提取特定字段将是一项简单的任务。UPDATE:回复OP评论:
试试这个逻辑:
use strict;
use warnings;
use WWW::Mechanize;
use LWP::Simple;
use File::Basename;
my $mech = WWW::Mechanize->new( autocheck => 1 );
$mech->get("http://millercenter.org/president/clinton/oralhistoryml");
# find all <dl> tags
my @list = $mech->find('dl');
foreach my $link (@list) {
my $url = $link->url();
my $localfile = basename($url);
my $localpath = "./$localfile";
print "$localfilen";
getstore($url, $localpath);
}
我的回答集中在如何做到这一点的方法上。我不提供代码。
链接中没有id,但采访页面的名称似乎可以使用。您需要解析它们并构建一个查找表。
基本上,你首先构建一个解析器来获取所有看起来像采访的链接。这在WWW::Mechanize中相当简单。页面URL为:
http://millercenter.org/president/clinton/oralhistory
所有的访谈都遵循以下模式:
http://millercenter.org/president/clinton/oralhistory/george-mitchell
所以你可以找到该页中所有以http://millercenter.org/president/clinton/oralhistory/
开头的链接。然后你让它们独一无二,因为有这个提示框滑动条展示了其中一些,它有一个到页面的read more链接。使用散列来做这样的事情:
my %seen;
foreach my $url (@urls) {
$mech->get($url) unless $seen{$url};
$seen{$url}++;
}
然后你获取页面,做你的东西,把它写到你的数据库。使用URL或URL中的面试人员姓名部分(例如goerge-mitchell
)作为主键。如果有其他的总统,你也想要那些,调整以防相同的名字出现在几个总统。
然后返回并在代码中添加缓存查找。在开始获取页面之前,从DB中获取所有id,并将它们放在散列中。
# prepare query and stuff...
my %cache;
while (my $res = $sth->fetchrow_hashref) {
$cache{$res->{id}}++;
}
# later...
foreach my $url (@urls) {
next if $cache{$url}; # or grab the ID out of the url
next if $seen{$url};
$mech->get($url);
$seen{$url}++;
}
你还需要过滤掉那些不是采访的链接。其中之一是http://millercenter.org/president/clinton/oralhistory/clinton-description
,它是页面上第一段的read more。