使用XPath进行webscrape。
结构为:
<table>
<tbody>
<tr>
<th>
<td>
但是这些tr之一仅包含1或1 td。
<table>
<tbody>
<tr>
<th>
所以我只想抓取TR
内是否包含两个标签。我在给路
$route = $path->query("//table[count(tr) > 1]//tr/th");
或
$route = $path->query("//table[count(tr) > 1]//tr/td");
但是它不起作用。
我在这里提供了orjinal表的链接。第一个表的最后两个TR是只有一个TD。那就是问题所在。第二表或第三表也有相同的问题。
https://www.daiwahouse.co.jp/mansion/kanto/tokyo/y35/gaiyo.html
$route = $path->query("//tr[count(*) >= 2]/th");
foreach ($route as $th){
$property[] = trim($th->nodeValue);
}
$route = $path->query("//tr[count(*) >= 2]/td");
foreach ($route as $td){
$value[] = trim($td->nodeValue);
}
我正在尝试同时选择TH和TD。但是,如果TR包含一个TD,则可以解决该问题。因为在和TD计数和TH计数不一样,所以我要刮擦更多的TD,而不是TH
答案 0 :(得分:3)
此XPath,
//table[count(.//tr) > 1]/th
将选择具有多个th
后代(无论是否存在table
)的所有tr
元素中的所有tbody
个元素。
此XPath,
//tr[count(*) > 1]/*
将选择具有多个子元素的tr
个元素的所有子元素。
此XPath,
//tr[count(th) = count(td)]/*
将选择tr
个元素的所有子元素,其中th
个孩子的数量等于td
个孩子的数量。
OP发布了指向该站点的链接。根元素位于xmlns="http://www.w3.org/1999/xhtml"
命名空间中。
答案 1 :(得分:0)
如果我理解正确,您是否希望th
中的tr
个元素包含两个元素?我认为这就是您所需要的:
//th[count(../*) = 2]
答案 2 :(得分:0)
我在答案中包含了一条更明确的路径,并附有or
语句以计算TH和TD元素
$html = '
<html>
<body>
<table>
<tbody>
<tr>
<th>I am Included</th>
<td>I am a column</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th>I am ignored</th>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th>I am also Included</th>
<td>I am a column</td>
</tr>
</tbody>
</table>
</body>
</html>
';
$doc = new DOMDocument();
$doc->loadHTML( $html );
$xpath = new DOMXPath( $doc );
$result = $xpath->query("//table[ count( tbody/tr/td | tbody/tr/th ) > 1 ]/tbody/tr");
foreach( $result as $node )
{
var_dump( $doc->saveHTML( $node ) );
}
// string(88) "<tr><th>I am Included</th><td>I am a column</td></tr>"
// string(93) "<tr><th>I am also Included</th><td>I am a column</td></tr>"
您还可以将其用于任何深度后代
//table[ count( descendant::td | descendant::th ) > 1]//tr
在条件(方括号部分)之后更改xpath以更改返回的内容。