PHP Dom抓取大量数据


PHP Dom Scraping large amount of data

我必须从8000多页x每页25条记录中收集一些数据。这大约有20多万张唱片。问题是服务器在一段时间后拒绝了我的请求。虽然我听说它相当慢,但我使用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内部服务器错误致命错误:调用D:''www''htdocs''ucmr''simple_html_dom.php中的非对象上的成员函数find(),位于1113

8846页确实存在,它是脚本的最后一页。上面的错误中的页码各不相同,所以有时我会在第800页收到错误。有人能告诉我在这种情况下我做错了什么吗。任何建议都会有帮助。

引发Fatal可能是因为$html$row不是对象,而是因为null。您应该始终尝试检查对象是否已正确创建。如果加载页面失败,方法$html->load_file($page);也可能返回false。

还要熟悉instanceof——有时它会很有帮助。

另一个编辑:您的代码根本没有数据验证。没有任何地方可以检查未初始化的变量、卸载的对象或执行时出现错误的方法。您应该始终在代码中使用这些。