2014-09-06 45 views
1

我解析一個房地產網頁,使用HTML :: TreeBuilder作爲,並具有以下代碼:HTML ::樹:無法調用「as_text」未定義的值

$values{"Pcity"} = $address->look_down("_tag" => "span", 
        "itemprop" => "addressLocality")->as_text; 
$values{"PState"} = $address->look_down("_tag" => "span", 
        "itemprop" => "addressRegion")->as_text; 

有些不包含城市或州,解析器退出並顯示錯誤:

Can't call method "as_text" on an undefined value 

要解決它,我用下面的方法:

$values{"Pcity"} = $address->look_down("_tag" => "span", 
        "itemprop" => "addressLocality"); 
if(defined($values{"Pcity"})) 
{ 
    $values{"Pcity"} = $values{"Pcity"}->as_text; 
} 
else 
{ 
    $values{"Pcity"} = ''; 
} 

它的工作原理,但現在,而不是1行,我有9。而且,因爲我有很多這樣的地方代碼將變得相當大。

有沒有什麼辦法可以優化?

回答

1

這是更短:

$a = $address->look_down("_tag" => "span", "itemprop" => "addressLocality"); 
$values{"Pcity"} = $a ? $a->as_text : ''; 
+0

這可以寫成'$值{Pcity} = $一個&& $ A-> as_text'具有最小差'$值{Pcity}'結束作爲'undef'而不是空字符串,如果沒有找到span元素。但請注意,除了'sort'語句塊之外,不應該使用'$ a'或'$ b',因爲這些標識符是保留的。 – Borodin 2014-09-06 23:06:03

+0

在這個例子中,使用$一個還沒有副作用 – 2014-09-07 07:06:16

+0

'$了'和'$ B'應避免理所當然的事,以同樣的方式使用'strict'和'warnings'編譯應始終包括在內,即使它們對特定程序沒有影響。沒有什麼可以說修改可能不會添加對'sort'的調用,並且引入一些不明確的錯誤。在這種情況下,你不知道OP的代碼是否已經包含'sort'。除此之外,'$ a'沒有用作標識符,因爲它是沒有意義的。 – Borodin 2014-09-07 12:57:28

2

假設$address決不會包含不止一個<span>與無論是對itemprop屬性給定值的,你可以寫這個

for my $span ($address->look_down(_tag => 'span')) { 
    my $itemprop = $span->attr('itemprop'); 
    $values{Pcity} = $span->as_text if $itemprop eq 'addressLocality'; 
    $values{PState} = $span->as_text if $itemprop eq 'addressRegion'; 
} 

但訪問HTML樹通過使用HTML::TreeBuilder::XPath變得簡單得多,這允許使用XPath表達式而不是笨拙的look_down對結構進行索引。使用它的解決方案看起來像這樣,條件是findvalue爲不存在的節點返回空字符串'',而不是undef;但這對你來說應該是可行的,因爲它仍然評估爲false

use strict; 
use warnings; 

use HTML::TreeBuilder::XPath; 

my $xp = HTML::TreeBuilder::XPath->new_from_file(*DATA); 

my %values; 

$values{Pcity} = $xp->findvalue('//span[@itemprop="addressLocality"]'); 
$values{PState} = $xp->findvalue('//span[@itemprop="addressRegion"]'); 

use Data::Dump; 
dd \%values; 

__DATA__ 
<html> 
<head> 
    <title>Title</title> 
</head> 
<body> 
    <span itemprop="addressLocality">My Locality</span> 
    <span itemprop="addressRegion">My Region</span> 
</body> 
</html> 

輸出

{ Pcity => "My Locality", PState => "My Region" } 
相關問題