2010-08-04 77 views
6

我“尝试”凑一个网页,拥有页面中的以下结构:如何使用CURL从页面解析实际的HTML?

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

我使用卷曲刮网页:

<?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。这就是我这样做:

​​

现在我不会假装我完全明白这一点,但我得到的要点,和我得到我想要的章节。唯一的问题是,我得到的仅仅是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。

回答

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>"; 
    } 
} 

这将只是打印每一个环节的身体。

+0

您也可以使用'foreach'代替'for'循环遍历节点。这将使它更加紧凑和易于理解,因为你实际上(似乎)不需要任何指标。 – janmoesen 2010-08-05 06:04:51

1

您可以将节点传递给DOMDocument::saveXML()。试试这个:

$printString = $newDom->saveXML($sections->item($i));

+0

是的,这将有效地返回节点的'outerHTML' – Gordon 2010-08-04 20:31:17

+0

显然,海报想要的是内部HTML,而不是外部。这对我来说并不明显,但无论如何,我都会将我的答案留给'saveXML'引用。 – janmoesen 2010-08-05 06:03:15