我必须收集8000多页的一些数据x每页25条记录。那是大约200,000条记录。问题是服务器在一段时间后拒绝我的请求。虽然我听说它很慢,但我使用simple_html_dom作为抓取库。这是样本数据:
<table>
<tr>
<td width="50%" valign="top" style="font-size:12px;border-bottom:1px dashed #a2a2a2;">Data1</td>
<td width="50%" valign="top" style="font-size:12px;border-bottom:1px dashed #a2a2a2;">Data2</td>
</tr>
<tr>
<td width="50%" valign="top" style="font-size:12px;border-bottom:1px dashed #a2a2a2;">Data3</td>
<td width="50%" valign="top" style="font-size:12px;border-bottom:1px dashed #a2a2a2;">Data4</td>
</tr>
</table>
php抓取脚本是:
<?php
$fileName = 'output.csv';
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-Disposition: attachment; filename={$fileName}");
header("Expires: 0");
header("Pragma: public");
$fh = @fopen('php://output', 'w');
ini_set('max_execution_time', 300000000000);
include("simple_html_dom.php");
for ($i = 1; $i <= 8846; $i++) {
scrapeThePage('url_to_scrape/?page=' . $i);
if ($i % 2 == 0)
sleep(10);
}
function scrapeThePage($page)
{
global $theData;
$html = new simple_html_dom();
$html->load_file($page);
foreach ($html->find('table tr') as $row) {
$rowData = array();
foreach ($row->find('td[style="font-size:12px;border-bottom:1px dashed #a2a2a2;"]') as $cell) {
$rowData[] = $cell->innertext;
}
$theData[] = $rowData;
}
}
foreach (array_filter($theData) as $fields) {
fputcsv($fh, $fields);
}
fclose($fh);
exit();
?>
正如您所看到的,我在for循环中添加了10秒的休眠间隔,因此我不会对请求强调服务器。 当它提示我下载CSV时,我在其中有这些行:
警告:file_get_contents(url_to_scrape /?page = 8846):无法打开流:HTTP请求失败! HTTP / 1.0 500内部服务器错误
致命错误:在 B13上的 D:\ www \ htdocs \ ucmr \ simple_html_dom.php 中的非对象上调用成员函数find()<11> < / b>
8846页面确实存在,它是脚本的最后一页。页码因上述错误而异,因此有时我会在第800页收到错误。 有人可以告诉我在这种情况下我做错了什么。任何意见将是有益的。
答案 0 :(得分:0)
投掷致命可能是因为$html
或$row
不是对象,而是null
。
您应该始终尝试检查对象是否已正确创建。如果加载页面失败,方法$html->load_file($page);
也可能返回false。
熟悉instanceof
- 它有时候会非常有用。
另一个编辑: 您的代码没有数据验证。您无法检查未初始化的变量,卸载的对象或执行错误的方法。您应该始终在代码中使用它们。