在for循环方式中使用请求promis时,nodejs中出现奇怪错误



我有以下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ée start(处理单个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));
}

最新更新