Как извлечь комментарии HTML и все HTML, содержащиеся в узле? - PullRequest
3 голосов
/ 19 мая 2011

Я создаю небольшое веб-приложение, которое поможет мне управлять и анализировать содержимое моих сайтов, и 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 содержит изображение и пару ссылок, он найдет их и вернет мне все как блок HTML.

Ответы [ 4 ]

13 голосов
/ 19 мая 2011

Узлы комментариев должны быть легко найдены в XPath с помощью теста comment(), аналогичного тесту text():

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

Это стандартные узлы: вот ручной ввод дляDOMComment класс .


К вашему другому вопросу это немного сложнее.Самый простой способ - использовать saveXML() с необязательным аргументом $node:

$html = $dom->saveXML($el);  // $el should be the element you want to get 
                             // the HTML for
1 голос
/ 19 мая 2011

Для комментариев 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;
     }

 }
0 голосов
/ 18 июня 2016
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;
      }
    }
  }
0 голосов
/ 29 мая 2013

для комментариев вы ищете рекурсивное регулярное выражение. Например, чтобы избавиться от html-комментариев:

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

чтобы найти их:

preg_match_all('/(<!--(?(?=<!--)(?R)|.)*?-->)/s',$yourHTML,$comments);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...