js代码批量删除CSDN 文章

在 LLM 出现之前,我常在谷歌上寻找各种编程问题的答案,经常就是搜到 CSDN 的技术文章,可见它出色的 SEO 效果。于是后期,我把公众号文章同步到了 CSDN,想借此提升文章的阅读量,并且也算是回馈社区。

开始的一段时间同步非常顺利,结果今年三月,一篇标题末尾含感叹号、问号和表情的文章触发了同步机制的 Bug,被疯狂复制出 60 多篇,累计展示和阅读突破十万。两次联系客服都没彻底解决,我只好先手动去掉公众号文章标题中的特殊符号,然后清理重复文章。发现 CSDN 并不支持批量删除,于是尝试了一下使用 Tampermonkey 脚本,一键全选、反选并批量删除。

js 代码用 o4-mini-high 制作,经过4轮对话,从开始不会展示按钮,不能删除文章,到最后成功点亮。

主要思路是模拟鼠标悬停触发下拉菜单,点击删除按钮。

  1. 等待文章渲染:轮询 .article-list-item-mp,一旦出现就开始注入。

  2. 动态插入工具栏:在列表顶部添加“全选”“反选”“批量删除”按钮。

  3. 给每行加复选框:方便批量勾选。

  4. 删除流程

  • 优先点击“彻底删除”按钮;

  • 找不到时,触发 mouseenter 打开下拉菜单,选中“删除”项并点击。

  • 兼容渲染延迟:多处 setTimeout/await 保证脚本稳定执行。


// ==UserScript==
// @name         CSDN 批量删除文章(悬停版)
// @namespace    http://tampermonkey.net/
// @version      0.6
// @description  支持“彻底删除”和鼠标悬停→“删除”两种模式的批量删除脚本。
// @match        https://mpbeta.csdn.net/mp_blog/manage/article*
// @match        https://blog.csdn.net/*/mp_blog/manage/article*
// @run-at       document-idle
// @grant        none
// ==/UserScript==

;(function(){
'use strict';

// 等到至少有一行文章出现
function waitForRow(){
    if(document.querySelector('.article-list-item-mp')){
      setup();
    } else {
      setTimeout(waitForRow, 300);
    }
  }

function setup(){
    // 插入工具栏(如果已经插过就跳过)
    if(document.getElementById('csdn-select-all')) return;
    const container = document.querySelector('.article_manage_list') || document.body;
    const bar = document.createElement('div');
    bar.style.cssText = 'padding:8px;background:#f5f5f5;border-bottom:1px solid #ddd;';
    bar.innerHTML = `
      <button id="csdn-select-all">全选</button>
      <button id="csdn-invert">反选</button>
      <button id="csdn-batch-del" style="color:red">批量删除</button>
      <span id="csdn-info" style="margin-left:16px;color:#666;"></span>
    `;
    container.prepend(bar);

    // 给每行加 checkbox
    function injectChecks(){
      document.querySelectorAll('.article-list-item-mp').forEach(item=>{
        if(item.querySelector('.csdn-checkbox')) return;
        const cb = document.createElement('input');
        cb.type = 'checkbox';
        cb.className = 'csdn-checkbox';
        cb.style.margin = '0 6px 0 0';
        item.querySelector('.list-item-mp-left').before(cb);
      });
    }
    injectChecks();

    document.getElementById('csdn-select-all').onclick = ()=> {
      document.querySelectorAll('.csdn-checkbox').forEach(cb=>cb.checked = true);
    };
    document.getElementById('csdn-invert').onclick = ()=> {
      document.querySelectorAll('.csdn-checkbox').forEach(cb=>cb.checked = !cb.checked);
    };

    document.getElementById('csdn-batch-del').onclick = async ()=>{
      const info = document.getElementById('csdn-info');
      const boxes = Array.from(document.querySelectorAll('.csdn-checkbox')).filter(cb=>cb.checked);
      if(boxes.length===0){ alert('请先勾选文章'); return; }
      if(!confirm(`确认删除 ${boxes.length} 篇文章?`)) return;

      for(let i=0; i<boxes.length; i++){
        const item = boxes[i].closest('.article-list-item-mp');
        const ops  = item.querySelectorAll('.item-info-oper-text');
        // 1) 优先“彻底删除”
        let btn = Array.from(ops).find(a=>a.textContent.trim()==='彻底删除');
        if(btn){
          btn.click();
        } else {
          // 2) 悬停触发下拉
          const toggler = item.querySelector('.el_mcm-dropdown .el-dropdown-link');
          toggler.dispatchEvent(new MouseEvent('mouseenter',{bubbles:true}));
          // 等菜单出来
          awaitnewPromise(r=>setTimeout(r, 400));
          // 找所有可见的菜单项
          const visible = Array.from(document.querySelectorAll('.el_mcm-dropdown-menu__item'))
            .filter(li=>li.offsetParent !== null && li.textContent.includes('删除'));
          if(visible.length){
            // 最后一个应该是“删除”
            const del = visible[visible.length-1];
            del.dispatchEvent(new MouseEvent('click',{bubbles:true,cancelable:true}));
          } else {
            console.warn('没找到 “删除” 菜单项', item);
          }
        }
        info.textContent = `已处理 ${i+1}/${boxes.length}`;
        // 等后端响应
        awaitnewPromise(r=>setTimeout(r, 1000));
      }
      info.textContent = '操作完成,建议刷新页面。';
    };

    // 监听新增行,补打 checkbox
    new MutationObserver(injectChecks).observe(container, {childList:true, subtree:true});
  }

  waitForRow();
})();

使用指南

  1. 安装 Tampermonkey:Chrome/Edge/Firefox 均支持。

  2. 新建脚本:复制粘贴上面“完整脚本”,保存并启用。

  3. 打开管理页:刷新 CSDN 文章管理页(/**/mp_blog/manage/article),稍等片刻即可见工具栏。

  4. 批量操作:勾选文章行左侧的复选框,点击「批量删除」即可自动清理。

在没有LLM的时代,油猴代码都是一行一行码的,想想都是泪。。

JS代码下载Shiny网页应用中的数据

油猴+JS代码创建DEAP网页按钮

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值