带有 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
我正在尝试抓取网页内容,使用 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