基于tr计数的XPath for td / th

时间:2019-01-25 03:21:43

标签: php html xml xpath

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

3 个答案:

答案 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"命名空间中。

请参见How does XPath deal with XML namespaces?

答案 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以更改返回的内容。