我正在使用PHP Simple HTML DOM使用以下HTML解析网页。请注意每个</span>
中的额外<li>
- 标记。
<li>
<span class="name">
<a href="">Link</a> asdasd
</span>
</span>
</li>
<li>
<span class="name">
<a href="">Link</a> asdasd2
</span>
</span>
</li>
我的疑问是:
$lis = $dom->find('li');
foreach ($lis as $li) {
$spans = $li->find('span');
foreach ($spans as $span) {
echo $span->plaintext."<br>";
}
}
我的输出是:
Link asdasd
Link asdasd2
-----------
Link asdasd2
-----------
正如您所看到的,find('span')
发现两个跨度作为第一个<li>
的子项,并从下一个<span>
中获取它可以找到的值(即使它是下一个的孩子) <li>
)。删除尾随</span>
可解决问题。
我的问题是:
为什么会这样?
我如何解决这个特殊情况? 其他一切都运作良好,我无法对我的剧本做出重大改变。如果需要,我可以轻松更改DOM查询。
我正在考虑计算开始和结束标记,如果有太多标记,则剥离一个</span>
。由于它们始终为<span>
s,是否有一种智能方法可以使用regexp进行检查?
答案 0 :(得分:1)
$newTxt = preg_replace('/\<\/span\>[\S]*\<\/span\>/','</span>',$txt);
方法'find(x)'是一个重载函数,可以返回等价的:
$e->getElementById(x);
$e->getElementsById(x);
$e->getElementByTagName(x); and
$e->getElementsByTagName(x);
在您的第一个电话中,它会使用最后一个电话。在第三种可能性的第二个$ li中。这可能是一种优化方法,根据API你要问的问题。我猜你在API中发现了一个错误,因为你在两种情况下都要求使用第三个调用:
$e->getElementByTagName();
答案 1 :(得分:1)
1)通过在某处添加</span>
来简单地尝试修复额外的<span>
。所以现在你有一个不应该存在的额外跨度。为了记录,DomDocument
会做同样的事情,尽管可能以更可预测的方式。
2)简化:
foreach ($dom->find('li > span') as $span) {
echo $span->plaintext."<br>";
}
// Link asdasd <br> Link asdasd2 <br>
现在你告诉它你只想要一个span
的孩子li
。更好的是,做一些事情:
foreach ($dom->find('span.name') as $span) {
echo $span->plaintext."<br>";
}
使用这些属性,这就是他们的好处。