我有以下web数据收集器:
function start(urls) {
Promise.map(urls, requestPromise)
.map((htmlPage, index) => {
const $ = cheerio.load(htmlPage);
$(".fixedttitle2").each(function () {
mytxt = $(this).text();
myarray.push(mytxt);
});
mainarray[urls[index]] = myarray;
});
fs.writeFileSync("1.json", JSON.stringify(mainarray));
}
var urls = [];
for (i = 1; i <= 100; i++) {
urls = "https://thisurl.com/" + i.toString();
start(urls);
}
现在我想首先检查每个请求的响应,如何首先检查响应代码,以消除一些返回500错误的URL?我该怎么处理?
您可能正在寻找这样的东西。
scrape
(néestart
(处理单个URL并返回承诺[url, content]
,如果出现错误,则返回[url, null]
main
生成要抓取的URL列表,然后为所有URL启动scrape
。- 注意所有100个请求同时启动;这对你来说可能是个问题,也可能不是
- 最后,当所有的scrape承诺完成时,它们的返回值被收集到
response
中,并被写入JSON文件中。- 这与原始文件的不同之处在于,原始文件在抓取新内容时不断重写文件
async function scrape(url) {
try {
const htmlPage = await requestPromise(url);
const $ = cheerio.load(htmlPage);
const texts = [];
$('.fixedttitle2').each(function () {
texts.push($(this).text());
});
return [url, texts];
} catch (err) {
console.error(`Error processing url: ${url}: ${err}`);
return [url, null];
}
}
async function main() {
const urls = [];
for (var i = 1; i <= 100; i++) {
urls.push(`https://thisurl.com/${i}`);
}
const response = await Promise.all(urls.map(scrape));
fs.writeFileSync('1.json', JSON.stringify(response));
}
如果您希望按顺序完成请求,可以在循环中使用await scrape()
:
async function main() {
const response = [];
for (var i = 1; i <= 100; i++) {
const url = `https://thisurl.com/${i}`;
response.push(await scrape(url));
}
fs.writeFileSync('1.json', JSON.stringify(response));
}
如果您想要与原始代码相同的增量行为,也可以将写文件调用移动到循环中。
编辑
您也可以在顺序循环中添加延迟:
// Basic promisified delay function
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
async function main() {
const response = [];
for (var i = 1; i <= 100; i++) {
const url = `https://thisurl.com/${i}`;
response.push(await scrape(url));
await delay(1000); // Wait for 1000 ms between scrapes
}
fs.writeFileSync('1.json', JSON.stringify(response));
}