PHP - 解析html文件

时间:2015-01-20 09:28:42

标签: php html dom

我需要解析一些html文件,问题是这个html的结构充满了我不关心的标签,而且我没有说明我会发现的内容。

我想直接在<p>标记下获取所有<body>标记,排除<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;   
     }    
   }   
}

我将迭代每个子节点并检查nodesName

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

2 个答案:

答案 0 :(得分:0)

可能不是最好的方法,但它可以为某人做好工作:

<?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>';
    }
}
?>

答案 1 :(得分:0)

我使用类似的代码来清理用他们发布内容的文章中的用户脚本片段,因此它可能会有所帮助,只需用你的内容替换数组中的标签即可。结果将是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