2

我希望在 Perl 问题上得到一些帮助。

我需要下载一个作为查询结果的 XML 文件,解析结果,从 XML 文件中获取下一个链接,下载并重复。

我已经能够很好地下载和解析第一个结果集。

我抓住了下一个 URL,但似乎返回的结果永远不会改变。即:第二次通过循环,$res->content和第一次一样。$url因此,第一次下载后 的值永远不会改变。

我怀疑这是一个范围问题,但我似乎无法解决这个问题。

use LWP::UserAgent;
use HTTP::Cookies;
use Data::Dumper;
use XML::LibXML;
use strict;

my $url = "http://quod.lib.umich.edu/cgi/f/findaid/findaid-idx?c=bhlead&cc=bhlead&type=simple&rgn=Entire+Finding+Aid&q1=civil+war&Submit=Search;debug=xml";

while ($url ne ""){

    my $ua = LWP::UserAgent->new();    
    $ua->agent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
    $ua->timeout(30);
    $ua->default_header('pragma' => "no-cache", 'max-age' => '0');

    print "Download URL:\n$url\n\n";

    my $res = $ua->get($url);

    if ($res->is_error) {
        print STDERR __LINE__, " Error: ", $res->status_line, " ", $res;
        exit;
    } 

    my $parser = XML::LibXML->new(); 
    my $doc = $parser->load_xml(string=>$res->content);

    #grab the url of the next result set
    $url = $doc->findvalue('//ResultsLinks/SliceNavigationLinks/NextHitsLink');

    print "NEXT URL:\n$url\n\n";

}
4

2 回答 2

0

我怀疑你得到的文件不是你所期望的。看起来您正在获取某种搜索页面,然后尝试抓取结果页面。确保 javascript 不对您的 fetch 不返回您期望的内容负责,就像在 this other question中一样。

此外,您可以尝试转储标题以查看是否可以找到其他线索:

use Data::Dumper;
print Dumper($res->headers), "\n";

顺便说一句,如果您还没有添加“使用警告”,您可能应该养成添加“使用警告”的习惯。

于 2011-02-15T06:41:59.007 回答
0

服务器可能只给你没有 HTTP_REFERER 的默认结果。我已经看到一些设置故意这样做以阻止抓取。

尝试这个:

在 while 循环之前,添加:

my $referer;

在您拥有之前:

# grab the result of...

加入:

$referer = $url

这样,您可以在将其重置为下一个之前保存上一个 URL。

然后,在您的 UserAgent 标头设置中,将其添加到:

    $ua->default_header(pragma => "no-cache", max-age => 0, Referer => $referer);

我不会肯定地说这是问题所在,但根据我的经验,这就是我要开始的地方。另一种选择是在 LWP 之外尝试。将所有 URL 记录到一个文件中,然后尝试 wget-ting 或 lynx --source-ing 从命令行查看是否得到与 LWP 提供的结果不同的结果。如果不是,那肯定是服务器正在做的事情,诀窍是找到一种解决方法,就是这样……解决技巧的方法就是更接近地复制常规 Web 浏览器的功能(因此,比较将您的标头发送到 Firefox 中的 Firebug 或 Safari 中的 Inspector 发送的标头会有很大帮助)

于 2011-02-15T20:46:51.217 回答