【问题标题】:Cannot open remote file to run Xpath on it无法打开远程文件以在其上运行 Xpath
【发布时间】:2014-09-20 17:26:38
【问题描述】:
<?php
    $ch = curl_init("http://www.alibaba.com/showroom/black-and-white-wedding-dresses.html");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    $html = curl_exec($ch);
    curl_close($ch);
    $dom = new DOMDocument;
    $dom->strictErrorChecking = false;
    @$dom->loadHTML($html);
    $xpath = new DOMXpath($dom);

    $description = $xpath->query('//meta[@name="description"]/@content');
    foreach ($description as $n) {
        echo $n->nodeValue ;
    }
?>

没有返回任何内容.. 使用其他 URL 可以正常工作。 可能是什么问题?

【问题讨论】:

    标签: php parsing xpath html-parsing


    【解决方案1】:

    您的 XPath 表达式很好。该站点正在执行用户代理检测并返回一个HTTP 302 响应,并将位置设置为请求的 IP 地址。将其转储到文件中以查看。

    如果您添加一个用户代理标头来模仿桌面浏览器,则请求将通过并且一切都会按预期工作。

    $ch = curl_init("http://www.alibaba.com/showroom/black-and-white-wedding-dresses.html");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1');
    $html = curl_exec($ch);
    curl_close($ch);
    $dom = new DOMDocument;
    $dom->strictErrorChecking = false;
    @$dom->loadHTML($html);
    $xpath = new DOMXpath($dom);
    
    $description = $xpath->query('//meta[@name="description"]/@content');
    foreach ($description as $n) {
        echo $n->nodeValue ;
    }
    

    输出:

    Black And White Wedding Dresses, You Can Buy Various High Quality Black And White Wedding Dresses Products from Global Black And White Wedding Dresses Suppliers and Black And White Wedding Dresses Manufacturers at Alibaba.com
    

    【讨论】:

      【解决方案2】:

      当我在 Safari 或 Chrome 的 DOM 检查器中检查该页面时,它显示 &lt;meta&gt; 元素(以及所有元素)位于 XHTML 命名空间(URI 为 http://www.w3.org/1999/xhtml 的命名空间)。我不知道为什么它们在那个命名空间中(原始标记没有指定它们在那个命名空间中,AFAICT),但它可以解释为什么你的 XPath 表达式没有选择它们:它要求一个元元素在 no 命名空间中。

      要解决此问题,请使用以下解决方法:

      $description = $xpath->query('//*[local-name() = 'meta' and
                                        @name="description"]/@content');
      

      这将找到元元素,无论它们位于哪个命名空间中。

      或者,为了更高效,创建一个名称空间解析器,将xhtml 前缀绑定到 xhtml 名称空间 URI,然后将此名称空间解析器与表达式一起使用

      $description = $xpath->query('//xhtml:meta[@name="description"]/@content');
      

      但后者仅适用于 meta 元素位于 XHTML 命名空间中的网页。

      【讨论】:

      • @derp:谢谢,我将不得不调查一下……这很奇怪。它位于 XHTML 命名空间中,但乍一看似乎并不遵守 XML 命名空间建议 (w3.org/TR/REC-xml-names)。
      • @derp HTML5 如何脱离 SGML?我认为 HTML 是 SGML 的应用程序。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-07
      • 1970-01-01
      • 2019-08-08
      相关资源
      最近更新 更多