2012-07-31 107 views
5

我正在編寫一個基本腳本,它只是從網頁中提取所有鏈接。它是用Perl編寫的,利用了我通過CPAN安裝的WWW :: Mechanize和HTML :: Treebuilder :: Xpath模塊。通過HTML Treebuilder XPath提取鏈接

我知道使用只有WWW :: Mechanize可以很容易地完成,但是也想學習使用XPath來完成它。

因此,腳本將解析整個網頁,並檢查每個錨標記的href屬性,提取鏈接並將其打印到控制檯/將其寫入文件。請注意,在下面的腳本中,我沒有使用strict,因爲我只寫這個來澄清和理解使用XPath遍歷HTML樹的概念。

這裏是腳本:

#! /usr/bin/perl 

use WWW::Mechanize; 
use HTML::TreeBuilder::XPath; 
use warnings; 

$url="https://example.com"; 

$mech=WWW::Mechanize->new(); 
$mech->get($url); 

$tree=HTML::TreeBuilder::XPath->new(); 

$tree->parse($mech->content); 

$nodes=$tree->findnodes(q{'//a'}); # line is modified later. 

foreach $node($nodes) 
{ 
    print $node->attr('href'); 
} 

它給出了一個錯誤:

Can't locate object method "attr" via package "XML::XPathEngine::Literal" at pagegetter.pl line 23. 

我已經修改了腳本如下:

$nodes=$tree->findnodes(q{'//a/@href'}); 

while($node=$nodes->shift) 
{ 
    print $node->attr('href'); 
} 

錯誤:

Can't locate object method "shift" via package "XML::XPathEngine::Literal" 

我不確定,如何打印href屬性的值。

$ nodes應該包含所有href屬性的列表?我相信它不會存儲價值,而是指向它的指針?

我試過搜索和閱讀的例子,但我不知道如何去做。

謝謝。

+0

您應該*總是*'使用strict',不管您的程序有多瑣碎。使用你選擇使用的警告是非常重要的。 – Borodin 2012-07-31 13:18:52

回答

4

有幾個錯誤。修理:

# list context 
my @nodes = $tree->findnodes(
    q{//a}  # just a string, not a string containings quotes 
); 

# iterate over array 
for my $node (@nodes) { 
+0

您應該使用'// a [@href]'的XPath來查找所有具有'href'屬性的錨元素 – Borodin 2012-07-31 13:19:36

+0

謝謝。同意,但你在For Loop內打印什麼?是的,我想提取鏈接? – 2012-07-31 13:23:08

+0

@NeonFlash:其餘代碼保持原樣。只要'print $ node-> attr('href'),「\ n」' – Borodin 2012-07-31 13:30:43