0

我正在使用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>可以解决问题。

我的问题是

  1. 为什么会这样?

  2. 我该如何解决这个特殊情况?其他一切都很好,我无法对我的脚本进行重大更改。如果需要,我可以轻松更改 DOM 查询。

我正在考虑计算开始和结束标签,</span>如果它们太多,则剥离一个。既然他们总是<span>s,有没有一种聪明的方法来用正则表达式检查它?

4

2 回答 2

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();
于 2013-08-05T00:37:17.450 回答
1

1) Simple 试图</span>通过添加<span>某处来修复你的额外内容。所以现在你有一个不应该存在的额外跨度。为了记录,DomDocument会做同样的事情,尽管可能以一种更可预测的方式。

2) 简化:

foreach ($dom->find('li > span') as $span) {
  echo $span->plaintext."<br>";
}
//     Link asdasd    <br>     Link asdasd2    <br>

现在你已经告诉它你只想要span那个是 a 的孩子的li。更好的是,执行以下操作:

foreach ($dom->find('span.name') as $span) {
  echo $span->plaintext."<br>";
}

使用这些属性,这就是它们的好处。

于 2013-08-05T01:38:12.813 回答