为什么这个 simple_html_dom 选择器在整体使用时不起作用,但在分解成更小的选择器时却不起作用?

Why doesn't this simple_html_dom selector work when used in entirety but not when broken into smaller selectors?

我正在使用 simple_html_dom 抓取一个页面。在我正在抓取的页面上,有一个 table 行,在这些行中,有一堆单元格。我想在每一行的第三个单元格中获取内容。有问题的单元格没有 class.

<tr class="thisrow">
  <td class="firstcell"><strong>1st</strong></td>
  <td class="secondcell">nothing in here</td>
  <td><strong>blah blah</strong></td>
  <td>something else</td>
</tr>

所以为了开始,我直接去了第三个单元格:

foreach($html->find('tr.thisrow td:nth-child(3)') as $thirdcell) {
    echo $thirdcell->innertext // this works, no problem!
}

但后来我意识到我需要行中另一个单元格中的一些数据 (td.firstcell)。这个单元格有一个 class,所以我认为最好遍历行,然后在该行的上下文中使用选择器:

foreach($html->find('tr.thisrow') as $row) {

    $thirdcell = $row->find('td:nth-child(3)');
    echo $thirdcell; // this is now empty

    $firstcell = $row->find('td.firstcell');
    echo $firstcell; // this works!

}

如您所见,我的第 n 个子选择器突然在行循环的上下文中不起作用。我错过了什么?

你可以使用children($int)方法。 $int0 开始。

试试这个:

$row = $html->find('tr.thisrow',0);

$firstcell = $row->children(2)->innertext;
$thirdcell = $row->children(0)->innertext;

你还有:first_child ()last_child()parent()next_sibling()prev_sibling()

这是simple html dom的限制。显然它可以处理 nth-child 选择器,但只有当父级位于您应用 find.

的节点下方的树中时

但它是一个有效的选择器,正如等效的 JavaScript 所示:

for (var row of [...document.querySelectorAll('tr.thisrow')]) {
    var thirdcell = row.querySelectorAll('td:nth-child(3)');
    console.log(thirdcell[0].textContent); // this works!
}
<table border=1>
<tr class="thisrow">
  <td class="firstcell"><strong>1st</strong></td>
  <td class="secondcell">nothing in here</td>
  <td><strong>blah blah</strong></td>
  <td>something else</td>
</tr>
</table>

作为解决方法,您可以在 find('td') 结果上使用数组索引:

foreach($html->find('tr.thisrow') as $row) {
    $thirdcell = $row->find('td');
    echo $thirdcell[2]; // this works
}

或者,或者 children,因为 tdtr 的直接子代:

foreach($html->find('tr.thisrow') as $row) {
    $thirdcell = $row->children();
    echo $thirdcell[2]; // this works
}