如何提取html注释和节点包含的所有html?

时间:2011-05-18 21:54:17

标签: php dom xpath curl

我正在创建一个小型网络应用程序来帮助我管理和分析我的网站内容,而cURL是我最喜欢的新玩具。我已经想出如何提取有关各种元素的信息,如何查找具有某个类的所有元素等,但我遇到两个问题(见下文)。我希望有一些漂亮的xpath答案,但如果我不得不诉诸正则表达式,我猜这没关系。虽然我对正则表达式不是那么好,所以如果你认为这是要走的路,我会欣赏这些例子......

非常标准的起点:

$ch = curl_init();
    curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
    curl_setopt($ch, CURLOPT_URL,$target_url);
    curl_setopt($ch, CURLOPT_FAILONERROR, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_AUTOREFERER, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);

    $html = curl_exec($ch);
    if (!$html) {
        $info .= "<br />cURL error number:" .curl_errno($ch);
        $info .= "<br />cURL error:" . curl_error($ch);
        return $info;
    }

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

    $xpath = new DOMXPath($dom);

和提取信息,例如:

// iframes
    $iframes = $xpath->evaluate("/html/body//iframe");
    $info .= '<h3>iframes ('.$iframes->length.'):</h3>';
    for ($i = 0; $i < $iframes->length; $i++) {
        // get iframe attributes
        $iframe = $iframes->item($i);
        $framesrc = $iframe->getAttribute("src");
        $framewidth = $iframe->getAttribute("width");
        $frameheight = $iframe->getAttribute("height");
        $framealt = $iframe->getAttribute("alt");
        $frameclass = $iframe->getAttribute("class");
        $info .= $framesrc.'&nbsp;('.$framewidth.'x'.$frameheight.'; class="'.$frameclass.'")'.'<br />';
    }

问题/问题:

  1. 如何提取HTML评论?

    我无法弄清楚如何识别评论 - 他们认为是节点还是其他东西?

  2. 如何获取div的整个内容,包括子节点?因此,如果div包含一个图像和几个href,它会找到这些并将它作为HTML块传回给我。

5 个答案:

答案 0 :(得分:13)

使用comment()测试在XPath中很容易找到注释节点,类似于text()测试:

$comments = $xpath->query('//comment()'); // or another path, as you prefer

它们是标准节点:here is the manual entry for the DOMComment class


对于你的另一个问题,它有点棘手。最简单的方法是使用saveXML()及其可选的$node参数:

$html = $dom->saveXML($el);  // $el should be the element you want to get 
                             // the HTML for

答案 1 :(得分:1)

对于HTML评论,快速方法是:

 function getComments ($html) {

     $rcomments = array();
     $comments = array();

     if (preg_match_all('#<\!--(.*?)-->#is', $html, $rcomments)) {

         foreach ($rcomments as $c) {
             $comments[] = $c[1];
         }

         return $comments;

     } else {
         // No comments matchs
         return null;
     }

 }

答案 2 :(得分:0)

该正则表达式 nvcc_setup_for_powershell.ps1
对您有帮助。

In regex Test

答案 3 :(得分:-1)

public function parse($source) {
  $comments = array();

  // multiline comment /* */
  $tmp = explode("/*", $source);
  foreach ($tmp as $t) {
    if (strpos($t, "*/") !== false) {
      $comment = explode("*/", $t)[0];
      $comment = trim($comment);
      if (!empty($comment)) $comments[] = "/* " . $comment . " */";
    }
  }

  // multiline comment <!-- -->
  $tmp = explode("<!--", $source);
  foreach ($tmp as $t) {
    if (strpos($t, "-->") !== false) {
      $comment = explode("-->", $t)[0];
      $comment = trim($comment);
      if (!empty($comment)) $comments[] = "<!-- " . $comment . " -->";
    }
  }


  $tmp = explode("//", $source);
  foreach ($tmp as $t) {
    if (empty($t)) continue;
    $pos = strpos($source, $t);
    if ($pos > 1) {
      if ($source[$pos-2] == "/" && $source[$pos-1] == "/") {
        $comment = trim(explode("\n", $t)[0]);
        if (!empty($comment)) $comments[] = "// " . $comment;
      }
    }
  }

答案 4 :(得分:-2)

您正在寻找递归正则表达式的评论。例如,要摆脱HTML评论:

preg_replace('/<!--(?(?=<!--)(?R)|.)*?-->/s',$yourHTML);

找到它们:

preg_match_all('/(<!--(?(?=<!--)(?R)|.)*?-->)/s',$yourHTML,$comments);