2016-06-11 9 views
0

Ich schreibe eine Seite mit simple_html_dom. Auf der Seite, auf der ich kratze, steht ein Tisch mit Reihen, in denen sich eine Reihe von Zellen befindet. Ich möchte in der dritten Zelle in jeder Reihe Zeug bekommen. Die fragliche Zelle hat keine Klasse.Warum funktioniert dieser simple_html_dom-Selektor nicht, wenn er vollständig verwendet wird, aber nicht, wenn er in kleinere Selektoren aufgeteilt wird?

<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> 

Also, um loszulegen, ging ich direkt für die dritte Zelle:

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

Aber dann in der Zeile in einer anderen Zelle einige Daten erkannte ich, ich brauchte (td.firstcell). Diese Zelle hat eine Klasse, so dass ich dachte, am besten in einer Schleife durch die Reihen, dann Selektoren im Rahmen dieser Reihe:

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! 

} 

So wie Sie, mein n-ter Kindselektor plötzlich in dem Kontext der sehen können Zeilenschleife funktioniert nicht. Was vermisse ich?

+0

könnten Sie das Ziel HTML für Test hinzufügen? – smoqadam

+0

@smoqadam, sicher, danke, ich habe es hinzugefügt. – willdanceforfun

Antwort

2

Es ist eine Begrenzung der simple html dom ist. Offenbar kann es mit nth-child Selektoren umgehen, aber nur, wenn das Elternteil in der Struktur unter dem Knoten ist, auf den Sie find anwenden.

Aber es ist ein gültiger Selektor, als das Äquivalent JavaScript zeigt:

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>

Als Abhilfe können Sie den Array-Index auf dem find('td') Ergebnis verwenden:

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

Oder alternativ mit children, als td sind direkte Kinder von tr:

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

Vielen Dank für die Erklärung, und auch eine wirklich gute Möglichkeit zu lehren, zu überprüfen, ob mein Wahlschalter richtig ist! Ich hätte mir nie vorstellen können, dass es eine Einschränkung des Pakets war. – willdanceforfun

1

können Sie children($int) Methode verwenden. $int Beginnen Sie mit 0.

versuchen Sie dies:

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

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

auch Sie haben: first_child(), last_child(), parent(), next_sibling(), prev_sibling()

Verwandte Themen