0

我知道有人问了一些类似的问题,但我有点卡在这里。我找不到任何好的教程来帮助我解决这个问题。但是我想做的应该是非常基础的。假设我想在 Stackoverflow.com 上获取 H1“热门问题”,使用 Chrome 获取 Xpath 我得到了这个:

//*[@id="h-top-questions"]

所以我的问题是;我现在如何回应这个?使用来自整个网络的代码片段,我得到了这个:

<?php
$curl = curl_init('http://stackoverflow.com/');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10');
$html = curl_exec($curl);
curl_close($curl);

if (!$html) {
    die("something's wrong!");
}

//var_dump(strlen($data));

$dom = new DOMDocument();
@$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

$headerh1 = $xpath->query('//*[@id="h-top-questions"]');

foreach($headerh1 as $match) {
    print_r($match);    
}
?>

我以为这只会输出<h1 id="h-top-questions">Top Questions</h1>。但相反,我得到了 DOMElement Object ( ) .

谁能帮帮我?我正在努力学习这个。

4

2 回答 2

1

您通过查询方法的结果获得一个 DOMNodeList 元素。DOMNodeList 尝试通过 item($index) 方法访问节点。

于 2012-05-21T08:53:00.333 回答
0

为了以这种方式查看对象的内容,您需要将其转换为字符串。如果你想这样做,你可以简单地echo/print它,或者把它转换成这样的字符串:

$string = (string) $object;

当一个对象被转换为一个字符串时,PHP 调用它的__toString()方法。不幸的是,一个 DOMElement 对象没有定义一个,所以当你尝试将它转换为字符串时,你会得到以下错误:

可捕获的致命错误:DOMElement 类的对象无法在...中转换为字符串

在这个特定的场景中,有一个穷人的解决方法,它允许人们用少量代码做到这一点,那就是使用函数通过SimpleXMLsimplexml_import_dom()反弹它——因为SimpleXMLElement该类确实定义了一个asXML()方法,它将它转换回XML 字符串。所以你可以这样做:

foreach($headerh1 as $match) {
  $xml = simplexml_import_dom($match);
  echo $xml->asXML();
}

但是,在此特定情况下,这会导致以下输出:

<h1 id="h-top-questions">&#13;
        Top Questions    &#13;
     </h1>

所以你看,有一些额外的 HTML 实体在其中泄漏,而这些实体不在原始源代码中。这发生在 DOM 和 SimpleXML 之间。

为了解决这个问题,可以:

  • 将输出传递给html_entity_decode(). 这不是一个很好的选择,因为它可能会导致无效的 XML/HTML 输出。
  • 滚动您自己的函数以将 DOMElement 转换为字符串。这也不是一个很好的选择,因为它会非常复杂,并且您可能需要通过许多级别递归才能成功检索完整节点列表。

但是,这里要记住的一件事是,除了测试和调试之外,您所做的事情并没有太多实际应用。人们永远不会真正想要输出部分文档。

于 2012-05-21T09:31:14.643 回答