延迟请求和cheerio模块的请求

所以这是我用来抓取我的网页的代码(我使用请求和cheerio模块:

for (let j = 1; j < nbRequest; j++) { const currentPromise = new Promise((resolve, reject) => { request( `https://www.url${j}`, (error, response, body) => { if (error || !response) { console.log("Error: " + error); } console.log("Status code: " + response.statusCode + ", Connected to the page"); var $ = cheerio.load(body); let output = { ranks: [], names: [], numbers: [], }; $('td.rangCell').each(function( index ) { if ($(this).text().trim() != "Rang") { output.ranks.push($(this).text().trim().slice(0, -1)); nbRanks = nb_ranks+1; } }); $('td.nameCell:has(label)').each(function( index ) { output.names.push($(this).find('label.nameValue > a').text().trim()); }); $('td.numberCell').each(function( index ) { if ($(this).text().trim() != "Nombre") { output.numbers.push($(this).text().trim()); } }); console.log("HERE 1"); return resolve(output); } ); }); promises.push(currentPromise); } 

之后,我parsing并使用节点模块将结果保存在csv文件中。 在这一点上,我已经能够抓取大约100页,但是当涉及到更多的数字(1000+)时,我收到了500个响应,这意味着我正在被踢,我想。 所以我认为最好的解决办法是延迟请求,但我没有find解决办法。 你们有什么想法,代码是怎么样的?

你正在寻找的是所谓的“控制stream”,你可以通过使用async.queue来实现这个例子。

如果将每个请求添加到队列中,则可以使用工作量来控制并行请求的数量。 你可以在请求callback的最后部分添加setTimeouts来实现请求的延迟。

此外,我build议使用“crawler”包(而不是自己构build),例如npm-crawler,因为它们随速度限制内置,并且已经处理了其他可能面临的问题,例如用户代理池

更新:

 const async = require("async"); const delayTime = 1500; //wait 1,5 seconds after every new request getRequestPromise(csvLine){ return new Promise( make you request here ); } const asyncQueue = async.queue(function(task, callback) { getRequestPromise(task).then(_ => { setTimeout(() => { callback(null); }, delayTime); }); }, 1); //1 one request at a time for(csv){ //pseudo asyncQueue.push(csv[i], () => {}); } asyncQueue.drain = () => { console.log("finished."); };