使用xpath PHP和domdocument获取某些表的内部内容来抓取数据


scraping data using xpath php and domdocument gettin inner content of certain table

有一个外部页面,我需要的数据。这是一种你可以从餐馆的订单中得到的列表。现在这个页面有表格…每个表都有一个类来说明它是哪种表,例如" delivered orders"

在这些表中有行和tds..我需要每一行的td值为我的数据数组…

所以我所做的…我使用类状态kitchen执行xpath查询,获取表的内容。这工作…但是现在我需要这个表中的所有行和TDS…由类分隔,例如<td class="orderode">0000</td>,我需要作为'ordercode' => val在我的数组..所以我在循环内又做了一个循环使用另一个xpath查询

但是现在我看到了所有的订单代码,不仅仅是厨房…因为它会再次解析整个HTML…我只是想在父foreach结果上做查询什么的。我该怎么做呢?

$result = array();
$html = $sc->login(); //curl result
$dom = new DOMDocument;
$dom->loadHTML($html);
$xPath = new DOMXPath($dom);
$classname = "order-link wide status-kitchen";
$td = $xPath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
foreach($td as $val){
    $classname = "code order-code";
    $td2 = $xPath->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]");
    foreach($td2 as $v){
        $result[] = $v->nodeValue;
    }
}
print_r($result);

HTML外观的示例:

/*厨房订购单*/

<table class="order-list">
      <tbody class="order-link wide status-kitchen" rel="#oQOP3PRN511"> // REPEAT
        <tr>
          <td class="time">17:43</td>
          <td class="time-delivery ">
            18:45           </td>
          <td class="code order-code">00000</td>
          <td>address data</td>
          <td class="distance">
                        </td>
          <td class="amount">€ 29,75</td>
        </tr>
      </tbody>
      <tbody class="order-link wide status-kitchen" rel="#oQOP3PRN511"> //REPEAT
        <tr>
          <td class="time">17:43</td>
          <td class="time-delivery ">
            18:45           </td>
          <td class="code order-code">00000</td>
          <td>address data</td>
          <td class="distance">
                        </td>
          <td class="amount">€ 29,75</td>
        </tr>
      </tbody>
</table>
/*order list deliverd */
<table class="order-list">
      <tbody class="order-link wide status-kitchen" rel="#oQOP3PRN511"> //REPEAT
        <tr>
          <td class="time">17:43</td>
          <td class="time-delivery ">
            18:45           </td>
          <td class="code order-code">00000</td>
          <td>address data</td>
          <td class="distance">
                        </td>
          <td class="amount">€ 29,75</td>
        </tr>
      </tbody>
      <tbody class="order-link wide status-kitchen" rel="#oQOP3PRN511"> //REPEAT
        <tr>
          <td class="time">17:43</td>
          <td class="time-delivery ">
            18:45           </td>
          <td class="code order-code">00000</td>
          <td>address data</td>
          <td class="distance">
                        </td>
          <td class="amount">€ 29,75</td>
        </tr>
      </tbody>

要从DOM中的给定节点开始运行第二个xpath查询,请从.开始查询,并将上下文节点作为第二个参数传递给query()

例子:

$td2 = $xPath->query(".//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]", $val);

您希望避免使用HTML DOM和类似的东西进行HTML抓取,因为它们不会处理某些类型的无效HTML,特别是在表方面存在问题。

获取所有trs:

preg_match_all( '~<tr.*?>(.*?)<'/tr>~is', $page, $trs );
foreach( $trs as $tr )
{
    preg_match_all( '~<td.*?>(.*?)<'/td>~is', $tr, $tds );
    print_r( $tds );
}

获取所有TR元素,有或没有属性,有或没有内部HTML。i标志表示不区分大小写,s标志表示它将包含'n in。匹配。对于TD也是如此。

查看我在这里发布的一个类,它做同样的事情:

获取内部HTML - PHP

虽然我已经很多年没有使用这个了,但我对函数不确定。我只是单独使用regex。

UPDATE:使用上面的类:

$c = new HTMLQuery( $html );
$tbs = $c->getElements( 'tbody', 'class', 'order-link wide status-kitchen' );
print_r( $tbs );
// you could then call a new HTMLQuery and query trs, etc., or:
foreach( $tbs as $tb )
{
    preg_match_all( '~<tr.*?>(.*?)<'/tr>~is', $tb, $trs );
    foreach( $trs as $tr )
    {
        preg_match_all( '~<td.*?>(.*?)<'/td>~is', $tr, $tds );
        print_r( $tds );
    }
}