编写脚本批量删除新浪微博内容

2026-08-05 71 浏览 0 评论

早期新浪微博开放平台提供正式的 statuses/destroy 删除接口,开发者可通过 OAuth 授权调用,实现程序批量删除微博。随着平台接口策略调整,开放平台该接口权限收紧,普通开发者无法再通过 OAuth 调用官方开放 API 完成批量删除操作。

网页版微博在前端操作删除时,依旧会调用内部 AJAX 接口完成删除逻辑。如果历史微博数量庞大,手动逐条点击删除效率极低。因此基于网页抓包拿到的内部接口,编写 Node.js 脚本,复用浏览器登录后的请求头凭证,实现自动化批量删除个人微博。

⚠️ 重要提示:本文脚本需要具备基础 Node.js 编程能力,脚本调用微博网页私有接口,接口随时可能变更失效;删除操作不可逆,执行前请做好内容备份;高频请求存在账号风控风险,请自行承担使用风险。

完整脚本如下,代码内部增加分段注释:

/* eslint-disable array-bracket-spacing */
/* eslint-disable prefer-const */
/* eslint-disable eqeqeq */
/* eslint-disable strict */
/* eslint-disable no-unused-vars */
/* eslint-disable no-undef */

// 引入依赖模块
const axios = require('axios');          // HTTP 请求库,用于调用微博接口
const { exec } = require('child_process');// 子进程模块,用于 pm2 停止进程
const fs = require('fs');                // 文件系统模块,读取 headers 配置文件
const path = require('path');            // 路径处理模块
const querystring = require('querystring'); // 参数序列化,把对象转为 form 表单格式

// axios 开启携带 Cookie 凭证,模拟浏览器请求
axios.defaults.withCredentials = true;

/**
 * 读取 weiboHeaders.txt 文件,解析为 HTTP 请求头对象
 * 文件内容为浏览器复制的完整请求头原始文本
 * @returns {Object} headers 请求头键值对
 */
function loadHeaders() {
  // 获取同目录下 weiboHeaders.txt 的完整路径
  const headersPath = path.join(__dirname, 'weiboHeaders.txt');
  // 读取文件全部内容,UTF‑8 编码
  const content = fs.readFileSync(headersPath, 'utf-8');
  // 按换行分割,过滤空行
  const lines = content.split('\n').filter(line => line.trim());
  const headers = {};
  // 需要跳过的请求头,axios 会自动生成,手动携带会冲突
  const skipHeaders = ['Host', 'Connection', 'TE', 'Accept-Encoding'];

  for (const line of lines) {
    // 跳过 HTTP 请求首行 GET / POST 行
    if (line.startsWith('GET ') || line.startsWith('POST ')) continue;
    const colonIndex = line.indexOf(':');
    // 没有冒号的行直接跳过
    if (colonIndex === -1) continue;
    // 分割请求头 key 与 value,并去除首尾空格
    const key = line.substring(0, colonIndex).trim();
    const value = line.substring(colonIndex + 1).trim();
    // 非空 key,且不在跳过列表中,则存入 headers 对象
    if (key && !skipHeaders.includes(key)) {
      headers[key] = value;
    }
  }
  return headers;
}

// 加载解析后的请求头
const headers = loadHeaders();

/**
 * 调用微博删除接口,删除单条微博
 * @param {string} WEIBO_ID 微博 ID
 * @returns {Object} 接口返回 data 数据
 */
async function destroyWeibo(WEIBO_ID = '5233926513099188') {
  const params = { id: WEIBO_ID };
  // POST 提交 form 表单格式参数,捕获异常避免单条失败直接中断整个脚本
  const res = await axios
    .post('https://weibo.com/ajax/statuses/destroy', querystring.stringify(params), { headers })
    .catch(() => ({ data: {} }));
  return res.data;
}

/**
 * 延时函数,Promise 封装 setTimeout,用于控制请求间隔,防止触发风控
 * @param {number} t 等待毫秒数
 * @returns {Promise}
 */
const delay = t => new Promise(r => setTimeout(() => r(), t));

/**
 * 获取当前用户的微博列表,调用 mymblog 接口
 * @returns {Array} 微博条目数组 list
 */
async function getUserWeiboTimeline() {
  const res = await axios
    .get('https://weibo.com/ajax/statuses/mymblog?uid=1848719402&page=1&feature=0', { headers })
    .catch(err => {
      console.log(err);
      // 请求异常返回空列表,脚本可以继续执行
      return { data: { data: { list: [] } } };
    });
  return res.data.data.list;
}

// 重试计数,当接口返回不足 20 条时做重试逻辑
let tryNum = 0;

/**
 * 脚本主逻辑:循环拉取微博列表,逐条删除,循环处理分页
 */
async function main() {
  // 获取一页微博列表
  const list = await getUserWeiboTimeline();
  console.log('获取数据条数:', list.length);

  // 如果返回列表为空,直接结束任务
  if (list.length == 0) done();

  // 遍历当前页所有微博,逐条执行删除
  for (let i = 0; i < list.length; i++) {
    let res = await destroyWeibo(list[i].id);
    // 根据接口返回 ok 字段判断删除结果,ok=1 代表成功
    console.log(list[i].id, res.ok && res.ok == 1 ? '删除成功' : '删除失败----------');
    // 随机 1‑3 秒延时,避免请求频率过高被限制
    let dtim = Math.floor(Math.random() * 3 + 1);
    console.log(new Date(), `等待${dtim}s`);
    await delay(Math.floor(1000 * dtim));
  }

  // mymblog 接口一页最多返回 20 条;返回 20 条说明还有下一页,递归继续执行
  if (list.length == 20) {
    tryNum = 0; // 重置重试计数
    await main();
  } else {
    // 返回不足 20 条,可能是全部删完,也可能接口缓存未刷新,进行有限次数重试
    tryNum++;
    if (tryNum > 7) done(); // 超过最大重试次数,结束脚本
    else {
      console.log(`获取数据不足 20 条(当前${list.length}条),第${tryNum}次重试...`);
      await delay(2000); // 等待 2 秒后重试拉取列表
      await main();
    }
  }
}

/**
 * 任务完成处理:pm2 停止进程,退出程序
 */
function done() {
  exec('pm2 stop destroyWeibo');
  process.exit();
}

// 启动脚本入口
main();

在脚本同级目录,创建 weiboHeaders.txt 文件,填入浏览器抓包复制的完整请求头原始内容:

抓包复制请求头

将抓包复制的全部请求头粘贴保存到 weiboHeaders.txt ,安装依赖后直接运行脚本即可:

执行脚本

注意:微博接口存在缓存现象,有时候接口返回条数为 0。遇到该情况,可以打开微博手机端,浏览个人微博多滑动几页刷新缓存,之后再重新运行脚本。

如果希望保留部分微博,可自行修改逻辑,在调用 destroyWeibo() 增加过滤条件,例如匹配微博正文关键字、指定微博 ID 跳过删除。如果保留的过多,则需要处理分页问题,不然每次获取的都是需要保留的内容。有什么问题欢迎留言讨论。

补充使用说明

  1. 安装依赖: npm install axios
  2. 修改脚本内 UID:将 getUserWeiboTimeline 接口 URL 中的 uid ,替换为你自己的微博 UID;
  3. 请求头来自浏览器 F12 网络面板,复制任意一条微博相关请求完整请求头;凭证存在有效期,Cookie 过期需要重新复制;
  4. 脚本使用 pm2 托管,如果不使用 pm2,可以删除 done() 函数里 exec 那一行,只保留 process.exit()
  5. 私有接口随时会变更字段、返回格式,脚本有可能在某一天直接失效。

发布评论

发布评论前请先 登录
0 评论
点赞
收藏

评论列表 0

暂无评论