You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Axios抓取网页数据后,如何正确将多条目写入JSON文件?

解决JSON写入仅保留最后一条&内容损坏的问题

嘿,我刚看完你的代码,马上就发现了两个核心问题导致你遇到的麻烦,咱们一步步来解决:

问题根源拆解

  • 每次循环都覆盖写入文件:你在$('li.article').each()循环里调用fs.writeFile,这个方法默认是覆盖模式——每迭代一次就把之前的文件内容完全替换掉,最后自然只剩最后一条数据。
  • 异步操作的竞态冲突:fs.writeFile是异步函数,循环里会快速触发多次写入请求,文件系统可能还没完成上一次写入,下一次就开始了,这会导致文件内容混乱损坏。
  • 未正确收集所有数据:你定义了prodArray但没真正用来存储所有爬取到的对象,而是每次循环都生成单个data直接写入,完全浪费了这个变量的作用。

修改后的完整代码(带详细注释)

const axios = require("axios");
const cheerio = require("cheerio");
const fs = require('fs').promises; // 改用Promise版的fs API,更适配异步流程
const colors = require("colors");

// 用数组存储所有爬取到的数据,数组是存储多个同类型对象的最佳选择
let prodArray = [];

axios.get("https://arstechnica.com/gadgets/")
  .then(urlResponse => {
    const $ = cheerio.load(urlResponse.data);
    $('li.article').each((i, elem) => {
      const link = $(elem).find("a.overlay").attr("href");
      // 用trim()去除文本前后的空白字符,避免数据里有多余的换行/空格
      const header = $(elem).find("h2").text().trim();
      const author = $(elem).find("p.byline").find("a").text().trim();

      console.log("---------------\n".red);
      // 规范JSON键名,去掉多余的空格和冒号,符合行业常规写法
      const data = {
        link: link,
        title: header,
        author: author
      };
      // 把当前数据对象添加到数组中,先攒着不着急写入
      prodArray.push(data);
    });

    // 等所有数据都爬取收集完成后,再一次性写入文件
    // JSON.stringify的第三个参数2,用来格式化输出(缩进2空格),让JSON文件更易读
    return fs.writeFile("verified.json", JSON.stringify(prodArray, null, 2));
  })
  .then(() => {
    console.log("所有数据已成功写入verified.json文件!".green);
  })
  .catch(err => {
    // 统一捕获所有错误:包括axios请求失败、文件写入失败等
    console.error("操作出错:", err.message.red);
  });

关键修改点解释

  1. 改用fs.promises.writeFile:
    基于Promise的API和axios的Promise链式调用完美契合,避免了回调嵌套,也能更优雅地处理异步流程,不会出现竞态冲突。

  2. 先收集所有数据再写入:
    循环里只把每个爬取到的data对象加入数组,等所有迭代完成后再一次性写入文件——彻底解决了覆盖写入的问题,也避免了多次写入的冲突。

  3. 优化数据格式:

    • 用trim()清理文本的空白字符,让数据更干净;
    • 把键名从"Link: "改成"link",去掉多余符号,让JSON结构更标准,后续读取数据也更方便。
  4. 统一错误处理:
    用.catch()捕获整个链式调用中的所有错误,不管是请求失败还是写入失败,都能得到清晰的错误提示,方便你排查问题。

新手友好小提示

  • 尽量避免用同步的fs.writeFileSync:它会阻塞Node.js的事件循环,数据量大的时候会拖慢程序性能,异步的Promise版本是更好的选择。
  • JSON.stringify的第三个参数非常实用:设置成数字(比如2)会格式化输出JSON,要是不设置,文件会是一行压缩的内容,可读性极差。

内容的提问来源于stack exchange,提问作者AlexF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 10:27:50