【问题标题】:PHP - parse html filesPHP - 解析 html 文件
【发布时间】:2015-01-23 00:10:10
【问题描述】:

我需要解析一些 html 文件,问题是这个 html 的结构充满了我不关心的标签,我没有说明我会找到什么。

我想直接在<body> 标记下获取所有<p> 标记,不包括<body> 的其他子节点并读取<p> 的子节点(如果有的话)(除了一些特定的标记,我可以管理一些例外)

例如:

<body>
  <node1>
    <p></p>
  <node1>
  <p></p>
  <p>
    <a>
    </a>
  <p>
</body>

我想排除 node1 及其子节点,获取所有其他节点 其实我的代码是:

$body = $dom->getElementsByTagName("body");
foreach($body as $node) {    
    if($node->childNodes->length) {    
    foreach($node->childNodes as $n) {  
        //insert here check: if nodeName != 'p'    
        $text .= $n->nodeName;   
     }    
   }   
}

我会遍历每个子节点并检查节点名称

如何在第一个查询中排除与p 不同的主体子节点?我试过$dom-&gt;getElementsByTagName("body/p");,但它不起作用 有没有更好的方法来管理和查询我的 HTML 文件? 谢谢

【问题讨论】:

  • 您介意通过jquery 解决它还是只清理javascript?
  • @Bandon 两者都不是,考虑到问题是关于 PHP 的。
  • 你也应该看看xpath
  • 我会用 xslt 来做这个

标签: php html dom


【解决方案1】:

可能不是最好的方法,但它可以为某人完成这项工作:

<?php
$html = "<!DOCTYPE html><head></head><body>
  <node1>
    <p>1</p>
  <node1>
  <p>2</p>
  <p>3
    <a>
    </a>
  <p>
</body>     
</html>
";      

$doc = new DOMDocument;
// our HTML might not be perfectly valid so we don't want to be warned about it
libxml_use_internal_errors(true);
$doc->loadHTML($html);
libxml_use_internal_errors(false);

// Count all p tags first
$ptagscntr = $doc->getElementsByTagName('p');
// if we have p tags
if ($ptagscntr->length) {
    // iterate
    for ($i=0;$i<$ptagscntr->length;$i++)  {
        // get each node
        var_dump($doc->getElementsByTagName('p')->item($i));
        echo '<br>----<br>';
    }
}
?>

【讨论】:

    【解决方案2】:

    我使用类似的代码从他们发布的带有内容的文章中清理用户脚本 sn-ps,因此它可能会有所帮助,只需将数组中的标签替换为您的标签即可。结果将是没有您指定的标签以及它们的下降的html

    $dom = new DOMDocument();
    
    // $body is your html you load into this variable elsewhere
    // Note that there will be a warning if any invalid tags like
    // node1 will be loaded, but in most cases it will continue to work
    @$dom->loadHTML($body);
    
    $tags_to_remove = array('node1', 'node2');
    
    // Collect and remove the tags with everything they hold.
    $remove = array();
    
    foreach ($tags_to_remove as $removal_target) {
        $sentenced = $dom->getElementsByTagName($removal_target);
    
        foreach ($sentenced as $item) {
            $remove[] = $item;
        }
    }
    
    foreach ($remove as $sentenced_item) {
        $sentenced_item->parentNode->removeChild($sentenced_item);
    }
    
    // Code below is used to get html without wrapping html>body and doctype
    // added by DOMDocument
    $body = '';
    
    $body_node = $dom->getElementsByTagName('body')->item(0);
    
    foreach ($body_node->childNodes as $child) {
        $body .= $dom->saveHTML($child);
    }
    

    Working code。请注意,将 html 加载到 dom 对象之前有错误抑制运算符@。举个例子,我用它来获得干净的输出,我强烈建议不要使用它。 More here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-11
      • 1970-01-01
      • 2018-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多