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

Puppeteer+Express API数据不更新问题求助

解决Puppeteer爬取股票数据API实时更新问题

核心问题分析

你遇到的问题本质是API数据未与爬取结果实时同步,nodemon重启时文件更新但接口返回空数组,大概率是文件读取缓存、写入不完整或内存数据未及时更新导致的。


具体解决方案

1. 实时读取文件,避免缓存

如果使用Express等框架,不要在启动时一次性将data.json读入内存,而是每次请求/data接口时重新读取文件:

// Express 示例(回调版)
const fs = require('fs');
const express = require('express');
const app = express();

app.get('/data', (req, res) => {
  fs.readFile('./data.json', 'utf8', (err, rawData) => {
    if (err) {
      console.error(err);
      return res.status(500).send('读取数据失败');
    }
    try {
      const data = JSON.parse(rawData);
      res.json(data);
    } catch (parseErr) {
      console.error(parseErr);
      res.status(500).send('数据格式错误');
    }
  });
});

或者用异步Promise版本:

// Express 示例(async/await版)
app.get('/data', async (req, res) => {
  try {
    const rawData = await fs.promises.readFile('./data.json', 'utf8');
    const data = JSON.parse(rawData);
    res.json(data);
  } catch (err) {
    console.error(err);
    res.status(500).send('读取数据失败');
  }
});

2. 增量更新数据,减少IO操作

不要每次爬取都覆盖整个data.json,对比新旧数据只更新变动项:

function updateChangedData(oldData, newData) {
  return oldData.map(oldItem => {
    const newItem = newData.find(item => item.code === oldItem.code);
    // 只更新价格、涨跌幅等有变化的字段
    if (newItem && (newItem.price !== oldItem.price || newItem.change !== oldItem.change)) {
      return { ...oldItem, ...newItem };
    }
    return oldItem;
  });
}

// 爬取逻辑中调用
const oldData = JSON.parse(fs.readFileSync('./data.json', 'utf8'));
const newStockData = await /* 你的Puppeteer爬取逻辑 */;
const updatedData = updateChangedData(oldData, newStockData);

// 仅当数据变化时写入文件
if (JSON.stringify(updatedData) !== JSON.stringify(oldData)) {
  fs.writeFileSync('./data.json', JSON.stringify(updatedData, null, 2));
}

3. 原子写入文件,避免读取空内容

nodemon重启时可能出现文件未写完就被读取的情况,改用原子写入(先写临时文件,再替换原文件):

const tempFilePath = './data.tmp.json';
// 先写入临时文件
await fs.promises.writeFile(tempFilePath, JSON.stringify(updatedData, null, 2));
// 替换原文件,保证原子性
await fs.promises.rename(tempFilePath, './data.json');

4. 改用内存存储数据(最优方案)

每秒更新场景下文件IO是瓶颈,直接将数据存在内存中,API直接返回内存数据:

// 全局变量存储实时股票数据
let realtimeStockData = [];

// Puppeteer定时爬取函数
async function crawlAndUpdateData() {
  const newData = await /* 你的Puppeteer爬取逻辑 */;
  // 增量更新内存数据
  realtimeStockData = updateChangedData(realtimeStockData, newData);
}

// API接口直接返回内存数据
app.get('/data', (req, res) => {
  res.json(realtimeStockData);
});

// 每秒执行一次爬取更新
setInterval(crawlAndUpdateData, 1000);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:36:25