【问题标题】:Fetch elements with DOMXPath使用 DOMXPath 获取元素
【发布时间】:2015-07-26 22:40:53
【问题描述】:

我想抓取 Google 搜索结果..

如何在不定义绝对路径的情况下获取所有<div class="g">元素?

此模式//h3[@class="r"] 将获取所有h3 元素

此模式//div[@class="g"] 不返回任何内容

html

...
    <div id="ires">
        <ol>
            <div class="srg">
                <div class="g">
                    ...
                        <h3 class="r"></h3>
                    ...
                </div>
                <div class="g">
                    ...
                        <h3 class="r"></h3>
                    ...
                </div>
            </div>
        </ol>
    </div>
...

代码

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.google.dk/search?q='.urlencode($query).'&start=0&num=100');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$html = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

libxml_use_internal_errors(true);
$doc = new DOMDocument('1.0', 'utf-8');
$doc->validateOnParse = false;
$doc->standalone = true;
$doc->preserveWhiteSpace = true;
$doc->strictErrorChecking = false;
$doc->substituteEntities = false;
$doc->recover = true;
$doc->formatOutput = true;
$doc->loadHTML($html);
libxml_clear_errors();

$div = $doc->getElementById('ires');

$xpath = new DOMXPath($doc);
foreach($xpath->query('//div[@class="g"]', $div) as $node){
    print_r($node);
}

【问题讨论】:

  • 您已经包含了一个简洁的示例和测试代码,这是一个好的开始。但是您实际上并没有解释运行此代码时当前发生的情况,以及您希望发生的情况。你有错误吗?是否显示了您不想要的元素?是否缺少您预期的输出?
  • 没有输出。我需要查询模式来获取所有&lt;div class="g"&gt; 元素,如问题中所述
  • 那么你的问题应该解释一下。点击edit并添加尽可能多的细节;我们不应该猜测或询问。
  • 你也可以尝试一些基本的调试(或者,如果你已经有,向我们展示结果):如果你转储$div会发生什么?如果你转储$xpath-&gt;query() 调用的结果,而不是循环它呢?您是否尝试过更简单的 XPath 表达式?
  • 我刚刚在在线测试服务中尝试了您的代码,它似乎工作正常:codepad.viper-7.com/lnDxE2 您是否尝试过使用这个确切的示例 HTML?也许您已经过度简化到无法再重现问题的地步?

标签: php html dom domxpath


【解决方案1】:

这行得通

try{
$ch = curl_init();
   if (FALSE === $ch)
    throw new Exception('failed to initialize');
    curl_setopt($ch, CURLOPT_URL, "https://www.google.ie/search?q=whereNotnull+laravel+5&ie=utf-8&oe=utf-8&gws_rd=cr&ei=FuezVfedF6aC7gaYiJiYBw");
    curl_setopt($ch, CURLOPT_USERAGENT, 'Firefox/14.0');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $content = curl_exec($ch);
  if (FALSE === $content)
    throw new Exception(curl_error($ch), curl_errno($ch));
curl_close($ch);
} catch(Exception $e) {
trigger_error(sprintf(
    'Curl failed with error #%d: %s',
    $e->getCode(), $e->getMessage()),
    E_USER_ERROR);
}

$dom = new DOMDocument();
$dom->loadHTML($content);
$xpath = new DOMXPath($dom);

选择所有具有“g”类的 div

   $xpath_resultset =  $xpath->query('//div[@class="g"]');

遍历 $hpath_result 节点

  foreach($xpath_resultset as $result){

将节点作为文本回显

   echo $dom->saveHTML($result);

将节点回显为 html 代码

   echo htmlspecialchars($dom->saveHTML($result)); // echo as html code
}

【讨论】:

  • 结果还是空
  • 虽然这里可能有一些有用的代码,但没有说明您所做的更改,或者这与问题中的示例有何关系。
  • 顺便说一句,curl 从不抛出异常,所以你的 catch 块完全没有意义。
  • @IMSoP 这个更好
  • 是的,这样好一点;我不认为它回答了这个问题,但我认为这是 OP 的错——原始代码已经为我工作了。不过,整个 curl 部分可能会被删除,因为问题包含 HTML 硬编码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-10
  • 2018-10-13
相关资源
最近更新 更多