【问题标题】:PHP Simple DOMDocument scraping exclude td classPHP Simple DOMDocument 抓取排除 td 类
【发布时间】:2017-12-29 04:08:39
【问题描述】:

我只是想获取驻留在<tr> 元素内的所有<td> 元素数据。我的问题是因为我试图抓取的表结构我需要排除所有具有COLLSPAN 属性的元素,即<td collspan = 12> 从下面的代码可以看出,获取表数据非常简单,但由于表结构的原因,我需要排除所有 collspan 属性。

<?php

$html = file_get_contents('http://www.superxv.com/fixtures/'); //get the html returned from the following url

$game_doc = new DOMDocument();
libxml_use_internal_errors(TRUE); //disable libxml errors
if(!empty($html)) { //if any html is actually returned
    $game_doc->loadHTML($html);
    libxml_clear_errors(); //remove error
    $xpath = new DOMXPath($game_doc);

    // Modify the XPath query to match the content
    foreach ($xpath->query('//table')->item(0)->getElementsByTagName('tr') as $rows) {
        $cells = $rows->getElementsByTagName('td');
        //$cells2 = $rows->getElementsByTagName('th');
        echo '<pre>';
         //@ signs are added due to table structure
        //Get scrapped columns
        echo $dayDateBye[] = $cells->item(0)->textContent;
        echo $homeTeam[] = $cells->item(1)->textContent;
        echo $awayTeam[] = $cells->item(2)->textContent;
        echo $venue[] = $cells->item(3)->textContent;
        echo $timeGMT[] = $cells->item(5)->textContent;
        echo $timeZA[] = $cells->item(10)->textContent;
        echo '</pre>';
    }
}

在这里您可以看到表格结构,它显示了 5 行奇数行的灯具,然后在新的一周开始时改变结构。我可以识别跳过这种结构变化的元素都是&lt;td collspan = 12&gt; 元素。这使得它变得棘手,因为 TD 元素没有类名,只有用于识别它的元素。

任何意见表示赞赏。

【问题讨论】:

  • 我不确定我是否理解你的问题,如果你想跳过提到的行,你可以做 count($cells) == 1,然后在循环中跳过它。

标签: php html web-scraping domdocument


【解决方案1】:

你可以按标签的长度跳过那些

<?php

$html = file_get_contents('http://www.superxv.com/fixtures/'); //get the html returned from the following url

$game_doc = new DOMDocument();
libxml_use_internal_errors(TRUE); //disable libxml errors
if(!empty($html)) { //if any html is actually returned
    $game_doc->loadHTML($html);
    libxml_clear_errors(); //remove error
    $xpath = new DOMXPath($game_doc);

    // Modify the XPath query to match the content
    foreach ($xpath->query('//table')->item(0)->getElementsByTagName('tr') as $rows) {
        $cells = $rows->getElementsByTagName('td');
        if( $cells->length > 1 ){
            //$cells2 = $rows->getElementsByTagName('th');
            echo '<pre>';
             //@ signs are added due to table structure
            //Get scrapped columns
            echo $dayDateBye[] = $cells->item(0)->textContent;
            echo $homeTeam[] = $cells->item(1)->textContent;
            echo $awayTeam[] = $cells->item(2)->textContent;
            echo $venue[] = $cells->item(3)->textContent;
            echo $timeGMT[] = $cells->item(5)->textContent;
            echo $timeZA[] = $cells->item(10)->textContent;
            echo '</pre>';
        }
    }
}

?>

【讨论】:

  • 非常感谢@Dhayal,我只是想了解答案,请您解释一下if( $cells-&gt;length &gt; 1 ){ 与按标签长度跳过究竟有何关系。非常感谢!
  • @TimothyCoetzee,我们正在循环行(tr)。根据表格,“colspan”有一个 td 孩子,其他行有多个孩子(td)。因此,我们基于此跳过。 $cells->length 将返回元素的子节点数(td 数)
  • 您可以简单地从原始集合中排除这些元素,而不是检查每次迭代的长度。
  • 感谢 Dhayal 现在非常有意义
【解决方案2】:

使用 xpath 排除具有colspan 属性的元素

所以而不是:

$cells = $rows->getElementsByTagName('td');

用途:

$cells = $xpath->query('td[not(@colspan)]', $rows);

【讨论】:

  • 非常简单实用。谢谢楼主
猜你喜欢
  • 2020-07-22
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 2017-06-08
  • 2011-06-09
  • 2013-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多