2013-02-28 81 views
3

我们已经有了一个带有静态信息的古老(内部)网站。我们将用更好的东西替换它,因此我需要获取所有信息。我使用通过正则表达式做到这一点,但最近我偶然发现一些文章指出,使用正则表达式来解析来自HTML的信息是inviting cthulhu to this realm解析HTML DOM方式

因此,我决定学习一些新的技巧,重新开始,并做到DOM方式。 的HTML一部分,我需要看起来像这样:

<table id="articles"> 
    <tr> 
    <th> 
     <a href='articles/aa123.html'><img src="/iamges/aa123.jpg" alt="some article"></a> 
     <br />short description 
    </th> 
    <td> 
     <table class='details'> 
     <tr><th><a href='articles/aa123.html'>Some Article</a></th></tr> 
     <tr><th>Type:</th><td>article type</td></tr> 
     <tr><th>Price:</th><td>€ 99</td></tr> 
     <tr><th>Manufacturer:</th><td>Some Company</td></tr> 
     <tr><th>Warehouse:</th><td>x</td></tr> 
     </table> 
    </td> 
</tr> 
</table> 

到目前为止,我得到这个:

$dom = new DOMDocument(); 
@$dom->loadHTMLFile ($file); 
$xpath = new DOMXPath($dom); 
$query = "/html/body/table[@id='articles']//th"; //catch all TH's 
$data = $xpath->evaluate($query); 

这是关于我卡住。我知道返回的TH的所有内容都在ChildNodes中,但我很难获取这些值。我需要详细信息页面的URL和Price列的值。

我如何获取这些提取?

目前,我想出了以下内容:

$query = '//table[@class="details"]//td'; 
$data= $xpath->evaluate($query); 
$c = $ths->length; 

for ($i = 0; $i < $c; $i++) { 
    echo htmlentities($data->item($i)->nodeValue);  
} 

但这仅显示从TD的文本值。当内容是链接时,它只显示链接标题。不是网址。

UPDATE 感谢Fab的建议,我设法预定了一些进展。目前,我得到了以下内容:

$tables = $xpath->query('//table[@class="details"]'); 
foreach($tables as $table) { 
    $url = $xpath->evaluate('//th/a/@href', $table); 
    $articleName= $xpath->evaluate('//th/a', $table); 
    $Manufacturer= $xpath->evaluate('//th[text()="Manufacturer:"]/../td', $table); 

    echo 'articleName:' . $articleName . ' <br />'; 
    echo 'Manufacturer:' . $Manufacturer. ' <br />'; 
    echo 'url:' . $url. ' <br />'; 
    echo '<br />'; 
} 

但由于某些原因,它总是显示从第一acticle(重复尽可能多的物品,因为在页面上)中的数据。就好像'foreach'语句总是返回第一个找到的表。有小费吗?

回答

1

的XPath的网址是:

//table[@class="details"]//th/[email protected] 

而对于价格列:

//table[@class="details"]//th[text()="Price:"]/../td 

也许你会想单独获得URL,价格为每个表,为此,你可以先收集具有所有“详细信息”表的DOMNodeList,然后在内部进行搜索(使用上下文参数):

$tables = $xpath->query('//table[@class="details"]'); 
foreach($tables as $table) { 
    $url = $xpath->evaluate('//th/[email protected]', $table); 
    $price = $xpath->evaluate('//th[text()="Price:"]/../td', $table); 
    echo "$url - $price <br>"; 
} 

UPDATE

我忘了一件事情:上下文参数只对相对路径有效,//th/...是绝对的。你必须在一开始加点:.//th/...

看一看:working demo

(我也不得不为query交换evaluate和显式访问的第一个项目的价值:

$xpath->query(...)->item(0)->nodeValue; 
+0

谢谢!我会尝试的(我一直在关注获取1查询CFR中的所有信息,我如何用正则表达式来完成) – Walter81 2013-02-28 14:45:06

+0

我取得了一些进展,但仍有一些缺失..请参阅上面的更新。 – Walter81 2013-03-01 10:04:19

+0

我明白了。答案更新:) – 2013-03-01 10:20:12