【问题标题】:PHP collecting filtered data from the second table of a HTML pagePHP 从 HTML 页面的第二个表中收集过滤数据
【发布时间】:2014-08-13 21:13:06
【问题描述】:

我最近在这里很快解决了一个解析问题,但这是一个我无法克服的新挑战。

这里有一个包含多个表格的(可怕的)html 页面:mxs link 我感兴趣的表格是代码的第二个,就在下面

<DIV CLASS="main"><H3>funrace.MXSConcept.com</H3><H3>Recent Races</H3>.

我需要收集所有的比赛,以便在下拉框中获得类似的东西:

40 minutes ago - 8M+1L at 2013 Motosport World GP Rd 09: Lommel (2 riders)
1 day ago - 8M+1L at 2013 EMF FrenchCup Rd5 : Lacapelle Marival (1 riders)
...
as for exemple $date is the date,
$race is the second column,
$link is hidden but is the URL of the first column (to use later in my dropdown)

注意: 日期似乎是用 js 动态生成的 somes lines talk about a new track record --> 这些行必须删除。

这是我尝试过的(嘿,别笑了伙计们!):

require('simple_html_dom.php');

    $doc = new DOMDocument;
    //$doc->preserveWhiteSpace = false;
    $doc->loadHTMLfile('http://mxsimulator.com/servers/mx.MXSConcept.com/');
    $xpath = new DOMXPath($doc);

    $table = array();
    $xpath = new DOMXPath($doc);

    $table2 = $doc->getElementsByTagName('table')->item(1);

    // collect data
    $data = array();
    foreach ($table2->query('//tr') as $node) {
        $rowData = array();
        foreach ($table2->query('td', $node) as $cell) {
            $rowData[] = $cell->nodeValue;
        }
    }

    print_r($data);

【问题讨论】:

  • 到目前为止的代码输出是什么?
  • Fatal error: Call to undefined method DOMElement::query() in /home/mxsconce/www/racing/results.php on line 56 没什么...

标签: php html xpath web-scraping domdocument


【解决方案1】:

首先,放弃require('simple_html_dom.php');,因为您使用的是DOMDocumentDOMXpath

其次,$table2->query('//tr') 这将失败,因为它不是 DOMXpath 对象。它是DOMElement

$dom = new DOMDocument();
$dom->loadHTMLFile('http://mxsimulator.com/servers/mx.MXSConcept.com/');
$xpath = new DOMXpath($dom);

$data = array();
// target each table row of the first table
$target_table_rows = $xpath->query('//div[@class="main"]/table[1]/tr');
// if there are rows found,
if($target_table_rows->length > 0) {
    // for each row, loop it
    foreach($target_table_rows as $row_key => $row) {
        // if the first td cell of this current row is empty
        if(trim($xpath->query('./td[1]', $row)->item(0)->nodeValue) == '') {
            continue; // then skip it
        }
        $data[] = array(
            'datetime' => $xpath->query('./td[1]', $row)->item(0)->nodeValue,
            'link' => $xpath->query('./td[1]/a', $row)->item(0)->getAttribute('href'),
            'description' => $xpath->query('./td[2]', $row)->item(0)->nodeValue,
        );
    }
}

echo '<pre>';
print_r($data);

输出应如下所示:

Array
(
    [0] => Array
        (
            [datetime] => 2014-08-14 15:32 UTC
            [link] => /servers/mx.MXSConcept.com/races/825.html
            [description] => 8M+1L at 2013 Johnson Mine MX (1 riders)
        )
    ... and so on

【讨论】:

  • 那里的输出不错:) 现在,是否有任何规则可以设置如果第一个 td 为空(正如我在问题中所问的那样)该行被忽略?我认为应该是你的if,但我仍然得到这些行
  • @Niko 好的,我已经跳过它检查修订版
  • 这是正确的方式。现在空单元格应被忽略,但 tr 的第二个 td 仍然存在(讲述跟踪记录)。因此,当单元格为空时,必须忽略整行。
  • @Niko 您的意思是跳过整行并且如果第一行 td 为空,则不要将其放入数组中?检查修订版
  • 就是这样!它有效,哇,语法真的很奇怪。谢谢你的技能 Ghost。
【解决方案2】:

你必须使用 $doc->加载(...) 对于外部文件。这里回答了一个类似的问题:Xpath and conditionally selecting descendants based on element value of ancestors

【讨论】:

  • 是的,我试过了,但我需要的规格(第二张桌子等)使它比我找到的其他帖子更难,而且我自己也无法解决。还是谢谢你
【解决方案3】:

这是我为获得所需链接所做的更新,但我确信有更简单的方法。 目标是在同一个数组中有链接,这里我必须有第二个:

$dom = new DOMDocument();
    $dom->loadHTMLFile($selectserv);
    $xpath = new DOMXpath($dom);
    $data = array();
    $links = array();
    // target each table row of the first table
    $target_table_rows = $xpath->query('//div[@class="main"]/table[1]/tr');
    // if there are rows found,
    if($target_table_rows->length > 0) {
        // for each row, loop it
        foreach($target_table_rows as $row_key => $row) {
            // if the first td cell of this current row is empty
            if(trim($xpath->query('./td[1]', $row)->item(0)->nodeValue) == '') {
                continue; // then skip it
            }
            // each td of this current row, push it inside the array data
            foreach($row->childNodes as $td) {
                $data[$row_key][] = $td->nodeValue;
            }

        }
        foreach($target_table_rows as $container) {
            $arr = $container->getElementsByTagName("a"); //get href tags
            foreach($arr as $item) {
              $href =  $item->getAttribute("href"); //get the href value I think ?
              $links[] = array(
                'href' => $href //put href in the array
              );
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多