3

我们有一个带有静态信息的古老(内部)网站。我们将用更好的东西替换它,因此我需要获取所有信息。我曾经通过正则表达式来做到这一点,但最近我偶然发现了一些文章,指出使用正则表达式从 HTML 解析信息正在邀请 cthulhu 进入这个领域

所以我决定学习一些新技巧,重新开始并以 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 和价格列的值。

我如何提取那些?

目前我想出了以下内容:

$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 的文本值。当内容是链接时,它只显示链接标题。不是网址。

更新 感谢 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 />';
}

但由于某种原因,它总是显示第一篇文章中的数据(重复页面上的文章数量)。好像“foreach”语句总是返回第一个找到的表。有小费吗?

4

1 回答 1

1

URL 的 XPath 将是:

//table[@class="details"]//th/a@href

对于价格列:

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

可能您希望分别获取每个表的 URL 和价格,为此您可以首先收集DOMNodeList所有“详细信息”表,然后在其中搜索(使用 context 参数):

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

更新

我忘了一件事:上下文参数只对相对路径生效,//th/...是绝对的。您必须在开头添加一个点:.//th/...

看看:工作演示

(我还必须交换evaluatequery显式访问第一项的值:

$xpath->query(...)->item(0)->nodeValue;
于 2013-02-28T14:11:21.307 回答