【问题标题】:PHP simple HTML DOM parsePHP 简单的 HTML DOM 解析
【发布时间】:2015-01-13 12:19:05
【问题描述】:

我想使用 dom 解析器从一些 html 代码中提取一些信息,但我卡在了一个点上。

<div id="posts">
    <div class="post">
        <div class="user">me:</div>
        <div class="post">I am an apple</div>
    </div>
    <div class="post">
        <div class="user">you:</div>
        <div class="post">I am a banana</div>
    </div>
    <div class="post">
        <div class="user">we:</div>
        <div class="post">We are fruits</div>
    </div>
</div>

这将打印用户。

$users= $html->find('div[class=user]');
foreach($users as $user)
    echo $user->innertext;

这将打印帖子。

$posts = $html->find('div[class=post]');
foreach($posts as $post)
    echo $post->innertext;

我想把它们打印在一起,而不是像这样分开打印:

me:
I am an apple
you:
I am a banana
we:
We are fruits

如何使用解析器做到这一点?

【问题讨论】:

  • DOMDocument 也许?
  • 如果你的html如你所见,你可以使用strip_tags()以非常简单的方式得到你的输出
  • strip_tags 会将代码与文本分开,不过我想做的是解析。

标签: php html simple-html-dom


【解决方案1】:

使用您提供的标记,您只需指出主 div (div#posts) 的子项,然后循环所有子项。然后为每个孩子获取第一个和第二个:

foreach($html->find('div#posts', 0)->children() as $post) {
    $user = $post->children(0)->innertext;
    $post = $post->children(1)->innertext;
    echo $user . '<br/>' . $post . '<hr/>';
}

虽然我真的建议使用DOMDocument :

$dom = new DOMDocument;
$dom->loadHTML($html_markup);
$xpath = new DOMXpath($dom);
$elements = $xpath->query('//div[@id="posts"]/div[@class="post"]');
foreach($elements as $posts) {
    $user = $xpath->evaluate('string(./div[@class="user"])', $posts);
    $post = $xpath->evaluate('string(./div[@class="post"])', $posts);
    echo $user . '<br/>' . $post . '<hr/>';
}

【讨论】:

  • 再次,如果我不知道是否还有更多的孩子怎么办?我想解析确切的特定 div。
  • @GeorgeIrimiciuc 的问题是,如果有多个 div 和这样的类怎么办?由于您提供的 html 标记在您想要的那些值上设置了特定位置,因此通过孩子们获得它似乎直截了当。无论如何,您也可以使用-&gt;class 属性来检查它,-&gt;class == "user"
【解决方案2】:

假设您使用的是Simple HTML DOM Parser,您可以使用find() 和逗号分隔格式。试试这个:

$posts = $html->find('div.post');
foreach($posts as $post){
  $children = $post->find('div.user,div.post');
  foreach($children as $child){
    echo $child->class.' -- ';
    echo $child->innerText(); echo '<br>';
  }
}

输出

user -- me:
post -- I am an apple
user -- you:
post -- I am a banana
user -- we:
post -- We are fruits

【讨论】:

  • 这个格式可以,但是如果我不知道有没有其他的孩子呢?
  • 不过,这不会对用户和帖子产生影响。
  • @GeorgeIrimiciuc $child-&gt;class 可以。
【解决方案3】:

使用下面的代码

$users= $html->find('div[class=user]');
$posts = $html->find('div[class=post]');
foreach($users as $i=>$user){
    echo $user->innertext."<br>";
echo $posts[$i]->innertext;
    }

希望对你有帮助

【讨论】:

  • 这将失败,因为“div class=post”的数量多于 div class=user 的数量。 (非常糟糕的格式设计)
猜你喜欢
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 2016-07-30
  • 2013-03-23
  • 2014-01-15
  • 2011-08-27
相关资源
最近更新 更多