如何使用CURL从页面解析实际的HTML?

时间:2010-08-04 19:48:09

标签: php html regex dom

我正在“尝试”抓取页面中具有以下结构的网页:

<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。

3 个答案:

答案 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