我正在“尝试”抓取页面中具有以下结构的网页:
<p class="row">
<span>stuff here</span>
<a href="http://www.host.tld/file.html">Descriptive Link Text</a>
<div>Link Description Here</div>
</p>
我正在使用curl抓取网页:
<?php
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, "http://www.host.tld/");
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$html = curl_exec($handle);
curl_close($handle);
?>
我做了一些研究,发现我不应该使用RegEx来解析从curl返回的HTML,并且我应该使用PHP DOM。这就是我这样做的方式:
$newDom = new domDocument;
$newDom->loadHTML($html);
$newDom->preserveWhiteSpace = false;
$sections = $newDom->getElementsByTagName('p');
$nodeNo = $sections->length;
for($i=0; $i<$nodeNo; $i++){
$printString = $sections->item($i)->nodeValue;
echo $printString . "<br>";
}
现在我并不是假装我完全理解这一点,但我得到了要点,我确实得到了我想要的部分。唯一的问题是,我得到的只是HTML页面的文本,就像我从浏览器窗口中复制它一样。我想要的是实际的HTML,因为我想提取链接并使用它们,如下所示:
for($i=0; $i<$nodeNo; $i++){
$printString = $sections->item($i)->nodeValue;
echo "<a href=\"<extracted link>\">LINK</a> " . $printString . "<br>";
}
正如您所看到的,我无法获取该链接,因为我只获得了网页的文字,而不是我想要的来源。我知道“curl_exec”正在拉HTML,因为我已经尝试过了,所以我相信DOM在某种程度上剥离了我想要的HTML。
答案 0 :(得分:4)
根据对the PHP manual on DOM的评论,您应该在循环中使用以下内容:
$tmp_dom = new DOMDocument();
$tmp_dom->appendChild($tmp_dom->importNode($sections->item($i), true));
$innerHTML = trim($tmp_dom->saveHTML());
这会将$innerHTML
设置为节点的HTML内容。
但我认为你真正想要的是在'p'节点下获得'a'节点,所以这样做:
$sections = $newDom->getElementsByTagName('p');
$nodeNo = $sections->length;
for($i=0; $i<$nodeNo; $i++) {
$sec = $sections->item($i);
$links = $sec->getElementsByTagName('a');
$linkNo = $links->length;
for ($j=0; $j<$linkNo; $j++) {
$printString = $links->item($j)->nodeValue;
echo $printString . "<br>";
}
}
这只会打印每个链接的正文。
答案 1 :(得分:1)
您可以将节点传递给DOMDocument::saveXML()
。试试这个:
$printString = $newDom->saveXML($sections->item($i));
答案 2 :(得分:0)
您可能需要查看phpQuery来执行服务器端HTML解析。 basic example