在Node.js+Cheerio中为Promise.map请求加延迟并排查500错误
Node.js爬虫优化:添加随机延迟并跳过500错误URL
以下是修改后的完整代码,解决了请求间无延迟、500错误导致中断的问题:
const requestPromise = require('request-promise'); const Promise = require('bluebird'); const cheerio = require('cheerio'); const fs = require('fs'); // 初始化变量 const urls = []; const shareTuple = {}; // 生成URL列表 for (let i = 1; i <= 250; i++) { urls.push(`https://mywebsite.com/${i}`); } // 生成随机延迟(1-3秒) const randomDelay = () => { const delayMs = Math.floor(Math.random() * 2000) + 1000; // 1000-3000毫秒 return Promise.delay(delayMs); }; // 自定义请求函数:先延迟,再请求,捕获500错误 const fetchUrl = async (url) => { await randomDelay(); try { return await requestPromise(url); } catch (e) { // 检测500错误,返回null标记 if (e.statusCode === 500) { console.log(`URL ${url} 返回500错误,已跳过`); return null; } // 其他错误仍抛出 throw e; } }; Promise.map(urls, fetchUrl, { concurrency: 1 }) .map((htmlOnePage, index) => { // 跳过返回null的错误URL if (!htmlOnePage) return; const $ = cheerio.load(htmlOnePage); const html44 = []; $('.txtSearch1').each(function () { let h = $(this).text().replace(/(\r\n|\n|\r)/gm, ""); html44.push(h); }); shareTuple[urls[index]] = html44; // 优化:改用异步写文件避免阻塞,或者批量写入 fs.writeFileSync("data.json", JSON.stringify(shareTuple)); }) .then(() => { console.log('爬取完成'); }) .catch((e) => console.log('遇到未处理的错误:', e));
关键改动说明:
- 添加随机延迟:
- 新增
randomDelay函数,生成1-3秒的随机等待时间,每次请求前先执行延迟,避免请求过于集中触发服务器限制。
- 新增
- 捕获并跳过500错误:
- 自定义
fetchUrl函数,包裹requestPromise调用,捕获请求错误。当检测到statusCode === 500时,打印日志并返回null,后续处理时跳过该URL。
- 自定义
- 修复变量未声明问题:
- 显式声明
urls、shareTuple等变量,避免全局变量污染。
- 显式声明
- 优化数据处理逻辑:
- 将
html44声明在每次循环内部,避免变量复用导致的混乱;简化文本处理代码。
- 将
- 完善流程反馈:
- 在
then中添加爬取完成的提示,错误捕获时打印具体错误信息,便于排查问题。
- 在
内容的提问来源于stack exchange,提问作者user6651939
相关产品推荐
相关产品推荐

