4

我正在尝试从以下内容中获取字符串“hinson lou ann”:

 <div class='owner-name'>hinson lou ann</div>

当我运行以下命令时:

$html = "http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339";
$doc  = new DOMDocument();
$doc->loadHTMLFile($html);
$xpath    = new DOMXpath($doc);
$elements = $xpath->query("*/div[@class='owner-name']");
if (!is_null($elements)) {
    foreach ($elements as $element) {
        echo "<br/>[" . $element->nodeName . "]";
        $nodes = $element->childNodes;
        foreach ($nodes as $node) {

            echo $node->nodeValue . "\n";
        }
    }
}

我收到以下错误:

警告:DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339中没有名称,行:1在 /home... 在线...

指的是线loadHTMLFILE

注意:该文件不是有效的 HTML,它只包含div标签!什么是我加载了文件然后在body上面打了 HTML 标签?

4

4 回答 4

9

如果你真的必须尝试解析它,试试这个:

<?php
$html = file_get_contents("http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339");
$doc = new DOMDocument();
$doc->strictErrorChecking = false;
$doc->recover=true;
@$doc->loadHTML("<html><body>".$html."</body></html>");

$xpath = new DOMXpath($doc);
$elements = $xpath->query("//*/div[@class='owner-name']");

if (!is_null($elements)) {
   foreach ($elements as $element) {
      echo "<br/>[". $element->nodeName. "]";
      $nodes = $element->childNodes;
      foreach ($nodes as $node) {
         echo $node->nodeValue. "\n";
     }
   }
 }
?>

PS:您的 XPath 错误,我已修复。你$nodes不会有任何东西,因为那个 DIV 元素 ( .owner-name) 没有任何子元素..所以你需要修改它。

于 2013-06-27T20:45:07.793 回答
3

只需从源代码构建一个 HTML 文档,将其包装在缺少的元素中就可以了。

例如:-

<?php
$html = file_get_contents('http://gisapps.co.union.nc.us/ws/rest/v2/cm_iw.ashx?gid=12339');
$html = sprintf('<html><head><title></title></head><body>%s</body></html>', $html);

$doc = new DOMDocument;
$doc->loadHTML($html);

$xpa    = new DOMXPath($doc);
$divs   = $xpa->query('//div[@class="owner-name"]');

foreach($divs as $div) {
    echo $div->nodeValue, PHP_EOL;
}

/*
    hinson lou ann
*/
于 2013-06-27T20:49:26.043 回答
3

您收到错误是因为您加载的 HTML 包含&字符而不是有效的 HTML 实体。缺少实体名称:

... <td>HINSON J MARK & WF LOU ANN G</td> ...
                      ^

在加载此类文档时,您将在这些情况下看到一个错误(如您所写):

警告:DOMDocument::loadHTMLFile(): htmlParseEntityRef: 没有名字

HTML Entity (reference)name的名称有关,按以下模式:

&name;
 ^^^^

但是,此错误不会导致实际加载该 HTML 的任何问题。DOMDocument 可以很好地处理这个(常见)错误(但是,您可能会在有问题的位置遇到中断)。

因此,您需要将该文件包装到<body>标签中的假设是错误的。在 HTML 中,<body>标签是可选的。

您的具体问题是您无法理解加载 HTML 文件如何调试它。只需使用该saveHTML方法输出可以成功加载的内容。这样做已经向您展示了该 URL 已成功加载。

这将引导您接下来指出 Xpath 表达式是错误的:

*/div[@class='owner-name']

尽管您对<body>标签的了解并不遥远:即使那个 HTML 片段不包含<body>标签,DOM 也会有它!虽然里面有两个标签:

body/*/*/div[@class='owner-name']

最常见的缩写形式是使用//which 允许不明确表示标签位于哪个深度级别:

//div[@class='owner-name']

另见:

于 2013-06-29T09:56:46.340 回答
1

远程站点可能会返回导致此警告的无效 HTML。DOMDocument并且DOMXPath在 HTML 错误的情况下非常宽容。如果调用后只有警告DOMDocument::loadHTML()并且其余代码产生有效结果,我建议您使用静音运算符抑制警告@

$doc = new DOMDocument();

// suppress warnings
$ret = @$doc->loadHTML($html);

// but check errors ...
if($ret === FALSE) {
    die('Parse error');
}
于 2013-06-27T20:38:42.690 回答