php 中的 DOMDocument

DOMDocument in php

提问人:Saikios 提问时间:2/13/2011 最后编辑:TemplarSaikios 更新时间:6/25/2020 访问量:21619

问:

我刚刚开始阅读有关 DOM 的文档和示例,以便抓取和解析文档。

例如,我有如下所示的部分文档:

    <div id="showContent">
    <table>
    <tr>
        <td>
         Crap
        </td>
    </tr>
<tr>
          <td width="172" valign="top"><a href="link"><img height="91" border="0" width="172" class="" src="img"></a></td>
          <td width="10">&nbsp;</td>
          <td valign="top"><table cellspacing="0" cellpadding="0" border="0">
              <tbody><tr>
                <td height="30"><a class="px11" href="link">title</a><a><br>
                    <span class="px10"></span>
                </a></td>
              </tr>
              <tr>
                <td><img height="1" width="580" src="crap"></td>
              </tr>
              <tr>
                <td align="right">
                    <a href="link"><img height="16" border="0" width="65" src="/buy"></a>
                </td>
              </tr>
              <tr>
                <td valign="top" class="px10">
                    <p style="width: 500px;">description.</p>
                </td>
              </tr>
          </tbody></table></td>
        </tr>
    <tr>
        <td>
Crap
        </td>
    </tr>
    <tr>
        <td>
         Crap
        </td>
    </tr>
    </table>
    </div>

我正在尝试使用以下代码来获取所有标签并分析其中是否有废话或信息:tr

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

$xpath = new DOMXPath($dom);


$tags = $xpath->query('.//div[@id="showContent"]');
foreach ($tags as $tag) {
    $string="";
    $string=trim($tag->nodeValue);
    if(strlen($string)>3) {
        echo $string;
        echo '<br>';
    }
}

但是,我只是得到了没有标签的剥离字符串,例如:

Crap

Crap
Title
Description

但我想得到:

<tr>
   <td>Crap</td>
</tr>
<tr>
   <a href="link">title</a>
</tr>

如何保留html节点(标签)?

php xml html 解析 domdocument

评论

3赞 netcoder 2/13/2011
参见 PHP 的 DOMDocument 中的 innerHTML
2赞 Gordon 2/13/2011
您的 XPath 与 div 匹配。要获取您显示的 HTML,您必须使用不同的 XPath Query/Queries,然后将结果传递给 。请澄清您想要得到什么。echo $dom->save($node)
0赞 Gordon 2/13/2011
这里根本不需要@netcoder innerHTML。
0赞 Saikios 2/13/2011
@Gordon,我正在尝试获取一个页面的信息并将其显示在另一个页面中,但是该页面在表格中列出了很多信息,有些是相关的,有些不是,我有我想要的图片、标题和描述,然后是样式、数字,我不在乎,但我想在 div 中获取 html 以分析数据的相关性, 通过我的代码,我得到了所有的字符串,我不知道它是 td、原始 td 还是其他东西(所有信息都在那个大 div 中)

答:

69赞 Gordon 2/13/2011 #1

如果你想使用 DOM,你必须理解这个概念。DOM 文档中的所有内容(包括 DOMDocument)都是一个 Node。

DOMDocument 是节点的分层树结构。它从根节点开始。该根节点可以具有子节点,所有这些子节点都可以单独具有子节点。基本上,a 中的所有内容都是某种节点类型,无论是元素、属性还是文本内容。DOMDocument

          HTML                               Legend: 
         /    \                              UPPERCASE = DOMElement
       HEAD  BODY                            lowercase = DOMAttr
      /          \                           "Quoted"  = DOMText
    TITLE        DIV - class - "header"
     |             \
"The Title"        H1
                    |
           "Welcome to Nodeville"

上图显示了具有一些节点的 DOMDocument。有一个根元素 (HTML) 有两个子元素(HEAD 和 BODY)。连接线称为轴。如果沿着轴向下移动到 TITLE 元素,您将看到它有一个 DOMText 叶。这很重要,因为它说明了一件经常被忽视的事情:

<title>The Title</title>

不是一个节点,而是两个节点。具有 DOMText 子项的 DOMElement。同样,这个

<div class="header">

实际上是三个节点:DOMElement 带有一个 DOMAttr 和一个 DOMText。由于所有这些属性和方法都继承自 DOMNode,因此必须熟悉 DOMNode 类。

实际上,这意味着您获取的 DIV 链接到文档中的所有其他节点。你可以一直到根元素,也可以随时向下到叶子。一切都在那里。您只需查询或遍历文档以获取所需信息即可。

是否通过迭代 or use 或 XPath 来做到这一点取决于您。你只需要明白,你不是在处理原始HTML,而是在处理代表整个HTML文档的节点。childNodesDIVgetElementByTagName()

如果您需要帮助从文档中提取特定信息,则需要阐明要从中获取哪些信息。例如,你可以问如何从表中获取所有链接,然后我们可以回答如下问题:

$div = $dom->getElementById('showContent');
foreach ($div->getElementsByTagName('a') as $link) 
{
    echo $dom->saveXML($link);
}

但是,除非您更具体,否则我们只能猜测哪些节点可能是相关的。

如果您需要更多有关如何使用 DOM 的示例和代码片段,请浏览我之前对相关问题的回答:

到现在为止,对于您在 DOM 中可能拥有的每个基本到中等用例,都应该有一个代码片段。

评论

2赞 Saikios 2/14/2011
谢谢 Gordon,我需要这样的东西来了解 dom 是如何工作的,但我认为我不能用它来抓取我需要的信息,因为它们不遵循任何标准,也没有类、id 或类似的东西,只有表格:(无论如何,这些信息对于学习如何使用它很有用=D
5赞 3/22/2012
+1 ...我一直在寻找通往诺德维尔的地图!
4赞 lokeshsk 3/12/2014 #2

要创建解析器,您可以使用 htmlDOM

它是用 php 编写的非常简单易用的 DOM 解析器。通过使用它,您可以轻松获取标签的内容。div

例如,查找属性值为 的所有标签。dividtext

$ret = $html->find('div[id=text]');

评论

1赞 metric152 6/20/2014
这对我来说做得更好。我正在使用一个非常糟糕的 html 的网站。domdocument 无法找到我想要的节点。这个库可以更好地处理糟糕的 html。