带有 DOMDocument 的网页抓取工具

Web scraper with DOMDocument

我正在尝试抓取网页内容,使用 file_get_contents 抓取 HTML,然后使用 DOMDocument object。我的问题是我无法获得适当的信息。我不确定这是否是因为我错误地使用了 DOMDocument 的方法,或者我源代码中的 (X)HTML 很差。

源码中有一个id为'cards'的元素,它有两个child div。我想要第一个 child,它有很多 child div,而后者又有一个 anchor child 和 div child.我想要 anchor 中的 href 和 child div 中的 nodeValue。

结构是这样的:

<div id="cards">
    <div class="grid">
        <div class="card-wrap">
            <a href="linkValue">
                <img src="..."/>
                <div>nameValue</div>
            </a>
        </div>
        ...
   </div>
   <div id="...">
   </div>
</div>

我从 $cards = $dom->getElementById("cards") 开始。我得到一个 DOMText Object、一个 DOMElement Object、一个 DOMText Object、一个 DOMElement Object 和一个 DOMText Object。然后我使用 $grid = $cards->childNodes->item(1) 获取第一个 DOMElement Object,这大概是 .grid 元素。但是,当我使用以下命令遍历 $grid 时:

foreach($grid->childNodes as $item){
    if($item->nodeName == "div"){
        echo $item->nodeName,' | ',$item->nodeValue,'<br>';
    }
}

我最终得到一个满是 "div | nameValue" 的页面,其中 nameValue 是嵌入的 div 的 nodeValue,我无法找到 anchor 的位置获取他们的 href 值。

我的 DOMDocument 是否有明显错误,或者这里可能还有其他问题?

好吧,从您的示例代码来看,if($item->nodeName == "div"){ 很可能会排除任何 <a> 标记。另外,我不相信 childNodes 允许递归迭代。

因此,要访问有问题的节点,您可以使用:

$children = $dom->getElementById("cards")->childNodes
                ->item(1)->childNodes->item(1)->childNodes;

然而,如您所见,这非常混乱...介绍 XPath:

XPath 方式:

$src = <<<EOS
<div id="cards">
    <div class="grid">
        <div class="card-wrap">
            <a href="linkValue">
                <img src="..."/>
                <div>nameValue</div>
            </a>
        </div>
   </div>
   <div id="whatever">
   </div>
</div>
EOS;

$xml = new SimpleXMLElement($src);

list ($anchor) = $xml->xpath('//div[@id="cards"]/div[1]/div[1]/a');
echo $anchor->div, ' => ', $anchor['href'], PHP_EOL;

"Get anchor of first child div of first child div of div with an id of 'cards'"

输出:

nameValue => linkValue