如何在 NodeJS 中创建循环以从 API 逐页获取数据并保存到文件? (节点、Axios、fs)

How to create loop in NodeJS to get page by page data from API and save to file? (Node, Axios, fs)

我需要从 API 获取所有数据。数据以批次(页面)的形式提供。每个批次都有其页码。

我的解决方案:

  1. 获取第1页,保存到文件
  2. 通过向页码添加 +1 循环并将 GET 请求的结果附加到文件
  3. 在没有错误的情况下继续

当前文件已创建,然后我得到:致命错误:堆限制附近的无效标记压缩分配失败 - JavaScript 堆内存不足

所以我使用--max-old-space-size=8192从那以后没有错误。它只是继续工作而没有结果。文件保持为空。

请帮忙!

const fs = require('fs');
const axios = require('axios');
const { response } = require('express');

var myWriteStream = fs.createWriteStream(
  '../dev-data/file.json',
  { flags: 'a' },
  { encoding: 'utf8' },
  err => {}
);

let pageNumber = 1;

// Getting initial batch on Page 1

axios
  .get(`https://api.example.com/?page=${pageNumber}`)
  .then(function (response) {
    var json = JSON.stringify(response.data);

// Saving result to the file

    fs.writeFile('../dev-data/declarations_list.json', json, 'utf-8', err => {
    });

// Looping GET + save to the file by adding + 1 to currentPage 

    do {
      pageNumber = response.data.page.currentPage + 1;
      axios
        .get(
            `https://api.example.com/?page=${pageNumber}`
        )
        .then(function (response) {
          console.log(`Current page: ${response.data.page.currentPage}`);
          pageNumber = response.data.page.currentPage;

          var json = JSON.stringify(response.data);

          myWriteStream.write(json);
        })
        .catch(function (error) {
          console.log(error);
        });

// Do while currentPage (no 'error')

    } while (response.data.page.currentPage);
  });

更新

const fs = require('fs');
const axios = require('axios');
const { response } = require('express');

let pageNumber = 0;

do {
  pageNumber = pageNumber + 1;
  console.log(pageNumber);
  axios
    .get(`https://public-api.nazk.gov.ua/v1/declaration/?page=${pageNumber}`)
    .then(function (response) {
      console.log(response);
      console.log(`Current page: ${response.data.page.currentPage}`);
      pageNumber = response.data.page.currentPage;
      var json = JSON.stringify(response.data);
      fs.appendFileSync('../dev-data/declarations_list.json', json);
    })
    .catch(function (error) {
      console.log(error);
    });
  
} while (pageNumber < 15000);

这没有经过测试(因为缺少 api 访问权限),但每次加载新页面时我都会尝试写入文件,基本上是这样的:

const fs = require('fs');
const axios = require('axios');
const { response } = require('express');

let pageNumber = 0;
var stream = fs.createWriteStream('../dev-data/declarations_list.json', {flags:'a'});

do {
  pageNumber = ++;
  axios
    .get(
        `https://api.example.com/?page=${pageNumber}`
    )
    .then(function (response) {
      console.log(`Current page: ${response.data.page.currentPage}`);
      pageNumber = response.data.page.currentPage;
      var json = JSON.stringify(response.data);
      stream.write(json);
    })
    .catch(function (error) {
      console.log(error);
    });
    // Do while currentPage (no 'error')
} while (pageNumber < <total_number_of_pages>);

stream.end();

也不要嵌套这些 axios 调用。没有必要这样做,可能会出现几个问题。 但是我认为最大的问题是您写入该流的方式。

除此之外,如果没有错误,您的循环将永远不会结束。您需要提供要检索的页面总数。

在我看来,如果您对此不是很有经验,那么您可能会先查找类似“Nodejs 和 Express 保存 JSON 对文件的响应”之类的内容,然后再继续...