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

Express抓取RSS存MongoDB时触发insertMany缓冲超时错误

错误原因
  • 核心问题是执行RSS写入逻辑时,Mongoose还没完成MongoDB连接建立,所有数据库操作被暂存在内部缓冲队列,等待10秒没被发送到数据库就触发buffering timed out报错。你看到的文档_id是Mongoose在本地缓冲阶段生成的,不是MongoDB服务端返回的,因此数据不会实际持久化。后台手动创建帖子功能正常,是因为人工操作时服务已经启动完成,数据库连接早已就绪。
  • 逻辑写法错误:insertMany被放在forEach循环内部,每遍历一条RSS条目就执行一次批量插入,相当于第1次插1条、第2次插2条、第3次插3条,短时间内发起N次重复写入请求,直接把缓冲队列堵死。
  • 代码语法错误:重复声明两次axios,且误将RSS接口请求返回的response对象当成后端路由的响应对象调用response.json(),该对象不存在这个方法会触发额外异常。
  • 所有异步Promise都没有统一错误捕获,异常直接抛到全局触发大量UnhandledPromiseRejection警告。
修复方案
  1. 执行RSS抓取逻辑前,显式等待Mongoose数据库连接建立完成,再启动后续流程
  2. 调整写入逻辑:先遍历完所有RSS条目,把全部待插入数据整理到数组后,只调用一次insertMany
  3. 增加去重校验:插入前根据帖子url判断内容是否已存在,避免重复写入
  4. 给所有异步操作加错误捕获,不要混淆第三方接口响应对象和自身服务的路由响应对象
  5. 如果是独立运行的抓取脚本,操作完成后主动关闭数据库连接,避免进程挂起
修正后代码(独立脚本版本)
const mongoose = require('mongoose');
const axios = require('axios');
const { FeedItem } = require('./models/feeditem');

// 替换为实际的MongoDB连接地址
const MONGO_URI = 'mongodb://localhost:27017/你的数据库名';
const TARGET_FEED_URL = 'https://zyjswiadomie.eu/feed';
const RSS_API_ADDRESS = `https://api.rssapi.net/v1/83ad97e138f1d43536d5d0660da98095/get?url=${TARGET_FEED_URL}`;

async function startRssCrawl() {
  try {
    // 等待数据库连接完成再执行后续操作
    await mongoose.connect(MONGO_URI);
    console.log('MongoDB连接就绪');

    // 拉取RSS源数据
    const { data: rssResponse } = await axios.get(RSS_API_ADDRESS);
    const waitToInsert = rssResponse.result.entries.map(item => ({
      title: item.title,
      text: item.description,
      url: item.link,
    }));

    // 过滤已存在的帖子,避免重复插入
    const existedPostUrls = (await FeedItem.find(
      { url: { $in: waitToInsert.map(item => item.url) } },
      'url'
    )).map(item => item.url);
    const finalInsertList = waitToInsert.filter(item => !existedPostUrls.includes(item.url));

    let insertResult = [];
    if (finalInsertList.length > 0) {
      insertResult = await FeedItem.insertMany(finalInsertList);
      console.log(`抓取完成,成功插入${insertResult.length}条新帖子`);
    } else {
      console.log('本次抓取无新内容,无需写入');
    }

    await mongoose.disconnect();
    return insertResult;
  } catch (error) {
    console.error('RSS抓取写入失败:', error);
    await mongoose.disconnect();
    process.exit(1);
  }
}

startRssCrawl();

如果这段逻辑是写在Express等web服务的路由中,不需要手动执行数据库连接/断开操作(服务启动时已经完成连接),只需要修正循环内重复调用insertMany、错误调用response.json()的问题即可,记得给所有异步操作添加catch捕获异常。

内容的提问来源于stack exchange,提问作者Maciej Urmański

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 00:04:09