Crawlee爬虫生成Dataset文件数量异常:有时少于预期3个
问题分析与解决方案
问题描述
我按照Crawlee文档操作,预期在storage/datasets/default目录下生成000000001.json、000000002.json和000000003.json共3个文件,但有时仅生成1个或2个文件。即使删除storage文件夹后重新运行,该问题仍时有发生。相关代码如下:
import { Dataset, CheerioCrawler } from 'crawlee'; const crawler = new CheerioCrawler({ // Function called for each URL async requestHandler({ request, body }) { // Save data to default dataset await Dataset.pushData({ url: request.url, html: body, }); }, }); await crawler.addRequests([ 'http://www.example.com/page-1', 'http://www.example.com/page-2', 'http://www.example.com/page-3', ]); // Run the crawler await crawler.run();
可能原因与解决办法
1. 部分爬取请求失败
部分请求可能因网络波动、目标站点反爬拦截(IP封禁、请求频率限制)等原因失败,导致未执行pushData写入数据。
解决措施:
- 开启调试日志查看请求详情:在爬虫初始化时添加日志配置,排查失败请求的具体原因
const crawler = new CheerioCrawler({ logger: { level: 'DEBUG' }, // 开启DEBUG级日志 requestHandler({ request, body }) { // ... 原有逻辑 }, }); - 配置请求重试机制:增加
maxRequestRetries参数,让失败请求自动重试const crawler = new CheerioCrawler({ maxRequestRetries: 3, // 最多重试3次 // ... 其他配置 }); - 模拟浏览器请求头:避免被目标站点识别为爬虫,添加User-Agent等头信息
const crawler = new CheerioCrawler({ requestHandlerOptions: { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36' } }, // ... 其他配置 });
2. Dataset批量写入机制导致数据未及时落地
Crawlee的Dataset默认采用批量写入策略,不会每条pushData都立刻生成文件。如果爬虫提前终止(如未处理完所有请求),缓存中的数据可能未写入文件。
解决措施:
- 爬虫运行结束后强制刷新Dataset:确保所有缓存数据写入文件
await crawler.run(); await Dataset.flush(); // 强制写入所有未落地的数据 - 调整批量写入配置(调试用):设置
batchSize: 1让每条数据即时写入(会影响性能,仅建议调试时使用)// 初始化Dataset时配置 await Dataset.open({ batchSize: 1 }); const crawler = new CheerioCrawler({ async requestHandler({ request, body }) { await Dataset.pushData({ url: request.url, html: body }); }, });
3. 异步流程未正确等待完成
若代码未在完整的异步上下文执行,可能导致程序提前退出,爬虫未处理完所有请求。
解决措施:
- 将代码包裹在异步自执行函数中,确保所有异步操作完成
(async () => { const crawler = new CheerioCrawler({ // ... 爬虫配置 }); await crawler.addRequests([ 'http://www.example.com/page-1', 'http://www.example.com/page-2', 'http://www.example.com/page-3', ]); await crawler.run(); await Dataset.flush(); })(); - 添加错误捕获,避免未处理的异常导致程序崩溃
(async () => { try { const crawler = new CheerioCrawler({ /* ... */ }); await crawler.addRequests([/* ... */]); await crawler.run(); await Dataset.flush(); } catch (err) { console.error('爬虫执行出错:', err); } })();
内容的提问来源于stack exchange,提问作者Rajesh
相关产品推荐
相关产品推荐

