使用要求和cheerio模块延迟请求
问题描述:
所以这是我用来抓取我的网页(我使用要求和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);
}
后我解析
,并保存结果在csv文件使用节点模块 在这一点上,我已经能够抓取大约100页,但是当涉及到更大的数字(1000+)时,我收到了500个响应,这意味着我被踢了,我想。 所以我认为最好的办法是延迟的要求,但我没有找到解决方案。 。你们有什么想法,以及如何代码将会是什么样子?
答
您要查找的内容称为“控制流”,例如,您可以通过使用async.queue来实现此目的。
如果每个请求添加到队列中,你可以控制与工人的数量并行请求量。您可以将setTimeouts添加到请求回调的最后部分,以实现延迟请求。
另外我建议采用“履带式”包(而不是建立自己的),例如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.");
};
我想我已经“控制流”通过为每个请求的承诺。在我的csv文件中,我收到了想要的订单中的数据。 现在我打算在每个之间添加一个延迟。 –
不是,你只是“控制秩序”,你的承诺将在同一时间得到解决。 –
得到它的async.queue,但你可以帮我添加setTimeout到请求的回调的最后部分? –