【问题标题】:Formatting scraped data - and limiting foreach loop格式化抓取的数据 - 并限制 foreach 循环
【发布时间】:2018-06-03 13:24:40
【问题描述】:

我用下面的代码解决了我最初的问题。我现在需要学习如何将返回的数据限制为前 5 行。如何限制 foreach 循环?

我正在从site 中抓取数据 - 我能够遍历 DOM 以获取我想要的表“LAST 1 MONTH (11/20/2017-12/19/2017)”,这是第三个或“2”。但是,我不能完全正确地得到输出。我需要将它包装在一个表中,每一行都包含代码中指定的 td。这是我正在使用的代码,但成功率有限:

<?php
    $html = file_get_contents('https://ninjatrader.isystems.com/Systems/TopStrategies'); 
    $doc = new DOMDocument();
    @$doc->loadhtml($html);
    $xpath = new DOMXPath($doc);

    echo "<table>";
    foreach($xpath->query('//table')->item(2)->getElementsByTagName('tr') as $rows) {
    $cells = $rows->getElementsByTagName('td');

    echo "<tr>
            <td>" . $cells->item(1)->textContent . "</td>
                <td>" . $cells->item(2)->textContent . "</td>
                <td>" . $cells->item(3)->textContent . "</td>
                <td>" . $cells->item(5)->textContent . "</td>
            </tr>";
    }
    echo "</table>";
?>

好的,我已经用上面的方法解决了我的问题。有没有更好的方法来做到这一点?

【问题讨论】:

  • @ 抑制错误。因此,如果 loadhtml 有任何问题,它不会将它们推送到浏览器(如果您正在执行命令行操作,也不会推送到屏幕)——请参阅 stackoverflow.com/questions/2002610/…
  • 感谢@DragonYen,所以这是一种简化的方法-> libxml_use_internal_errors(TRUE); ?

标签: php web-scraping


【解决方案1】:

您可以通过 nodeName 属性访问标签名称,然后将标签的其他部分作为字符串添加到输出中。

echo "<" . $cells->item(1)->nodeName . ">";
echo $cells->item(1)->textContent;
echo "</" .  $cells->item(1)->nodeName . ">";

对“td”元素的更雄辩的方法:

for($i = 1; $i < 6; $i++)
{        
    if ($i != 4 && $cells->length > 4) {
         echo "<td>" . $cells->item($i)->textContent . "</td>";
    }
}

对于主循环,我会这样写,并将每个元素输出到新行。如果不需要新行,请删除“\n”。您可以使用数组键作为 $index 来限制 foreach 循环。因为在这种情况下第 0 行是空的,所以 $index &lt; 6 获取前 5 行。如果第 0 行有数据,你可以使用$index &lt; 5

$rows = $xpath->query('//table')->item(2)->getElementsByTagName('tr');
echo "<table>\n";
foreach($rows as $index => $row) {
  $cells = $row->getElementsByTagName('td');
  if ($cells->length > 4 && $index < 6) {
    echo "<tr>\n";
    for($i = 1; $i < 6; $i++)
    {        
      if ($i != 4) {
        echo "<td>" . $cells->item($i)->textContent . "</td>\n";
      }
    }
    echo "</tr>\n";
  }
}
echo "</table>\n";

参考资料:

http://php.net/manual/en/class.domxpath.php

http://php.net/manual/en/control-structures.for.php

http://php.net/manual/en/control-structures.foreach.php

【讨论】:

  • 关闭,但会在顶部输出一堆“”,然后将一些内容包装在类似 xml 的标签中......
  • 我编辑了我的答案以修复内容标签。顶部肯定有一个空白行,所以我用长度过滤掉它。
  • 效果很好。在“更雄辩”的方法中,for 循环是否只是替换了 foreach?
  • for 循环仅用于 td 元素。主循环的答案已更新。
  • 谢谢,从中学到了一些新东西。参考文献也很好!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 2014-09-28
  • 1970-01-01
相关资源
最近更新 更多