news 2026/4/3 4:15:37

【QQ】空间说说批量删除脚本(不用任何额外插件,打开F12控制台即可使用)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【QQ】空间说说批量删除脚本(不用任何额外插件,打开F12控制台即可使用)

原创,原因是不想配油猴,之前的脚本又太老,就自己写了一个。

一、脚本

1.内容

// 一键批量删除说说(支持自定义页面数量)(()=>{constdelay=2000;letcurrentIndex=0;letlistItems=[];letdialogObserver=null;letisProcessing=true;lettotalPagesToDelete=0;letpagesDeleted=0;// 1. 询问用户要删除的页面数量functionaskPageCount(){constinput=prompt('请输入要连续删除的页面数量(请输入数字):','5');if(input===null){console.log('用户取消了操作');returnnull;}constpageCount=parseInt(input);if(isNaN(pageCount)||pageCount<=0){alert('请输入有效的正数!');returnnull;}returnpageCount;}// 2. 自动查找iframefunctionfindIframe(){// 尝试多种方式找到包含日志的iframeletiframe=document.querySelector('iframe.app_canvas_frame')||document.querySelector('iframe[src*="app.qzone"]')||document.querySelector('iframe[src*="qzone"]');if(!iframe){// 遍历所有iframe,查找包含#msgList的constiframes=document.querySelectorAll('iframe');for(letframeofiframes){try{constdoc=frame.contentDocument;if(doc&&doc.querySelector('#msgList')){iframe=frame;break;}}catch(e){// 跳过跨域iframe}}}if(!iframe){console.log('未找到包含日志的iframe');returnnull;}try{returniframe.contentDocument||iframe.contentWindow.document;}catch(e){console.log('无法访问iframe内容');returnnull;}}// 3. 自动点击确认对话框functionsetupDialogMonitor(){if(dialogObserver)return;dialogObserver=newMutationObserver((mutations)=>{for(letmutationofmutations){if(mutation.addedNodes.length>0){for(letnodeofmutation.addedNodes){if(node.nodeType===1&&(node.matches('.qz_dialog_layer')||node.querySelector?.('.qz_dialog_layer'))){console.log('检测到确认对话框');setTimeout(()=>{constconfirmBtn=document.querySelector('a[title="点击这里确认"]');if(confirmBtn){confirmBtn.click();console.log('已点击确认按钮');}},300);}}}}});dialogObserver.observe(document.body,{childList:true,subtree:true});}// 4. 查找分页控件并跳转到上一页functiongoToPreviousPage(iframeDoc){constpager=iframeDoc.querySelector('p.mod_pagenav_main');if(!pager){console.log('未找到分页控件');returnfalse;}// 获取pager的所有子元素(包括a和span)constchildren=Array.from(pager.children);if(children.length<3){console.log('分页元素不足,可能是最后一页');returnfalse;}// 倒数第三个元素(因为倒数第一是"下一页",倒数第二是"当前页")constprevPageElement=children[children.length-3];if(!prevPageElement||prevPageElement.tagName!=='A'){console.log('未找到上一页链接');returnfalse;}// 检查是否是可点击的链接(不是disabled状态)if(prevPageElement.classList.contains('mod_pagenav_disable')||prevPageElement.style.pointerEvents==='none'){console.log('上一页不可点击');returnfalse;}console.log('正在跳转到上一页...');prevPageElement.click();returntrue;}// 5. 处理单条说说functionprocessItem(li){returnnewPromise((resolve)=>{consttrigger=li.querySelector('.dropdown-trigger');if(!trigger){resolve(false);return;}// 滚动到元素li.scrollIntoView({behavior:'smooth',block:'center'});setTimeout(()=>{trigger.click();setTimeout(()=>{constdeleteBtn=li.querySelector('.del.del_btn.author_display');if(deleteBtn){deleteBtn.click();console.log(`已点击删除按钮 (${currentIndex+1}/${listItems.length})`);// 等待确认对话框被自动处理setTimeout(resolve,1000);}else{resolve(false);}},500);},500);});}// 6. 显示进度信息functionshowProgress(){console.log(`进度:${pagesDeleted}/${totalPagesToDelete}页面`);console.log(`剩余:${totalPagesToDelete-pagesDeleted}个页面`);}// 7. 处理单个页面asyncfunctionprocessPage(){constiframeDoc=findIframe();if(!iframeDoc){console.log('无法访问iframe,停止处理');isProcessing=false;returnfalse;}listItems=iframeDoc.querySelectorAll('#msgList li.feed.feed_private');if(listItems.length===0){console.log('当前页面没有说说,尝试跳转到上一页');// 尝试跳转到上一页if(goToPreviousPage(iframeDoc)){console.log('等待新页面加载...');awaitnewPromise(resolve=>setTimeout(resolve,3000));returntrue;// 继续处理}else{console.log('没有更多页面可处理');returnfalse;// 停止处理}}console.log(`当前页面找到${listItems.length}条说说,开始删除...`);// 启动对话框监视器setupDialogMonitor();// 处理当前页所有说说for(leti=0;i<listItems.length;i++){currentIndex=i;console.log(`处理第${i+1}/${listItems.length}条说说...`);constsuccess=awaitprocessItem(listItems[i]);if(!success){console.log(`${i+1}条说说处理失败,跳过`);}// 如果不是最后一条,等待延迟if(i<listItems.length-1){console.log(`等待${delay/1000}秒...`);awaitnewPromise(resolve=>setTimeout(resolve,delay));}}console.log('当前页面所有说说已删除!');pagesDeleted++;showProgress();// 等待一小段时间让页面稳定awaitnewPromise(resolve=>setTimeout(resolve,1000));// 检查是否已达到指定的页面数量if(pagesDeleted>=totalPagesToDelete){console.log(`已达到指定的${totalPagesToDelete}个页面,停止处理`);returnfalse;}// 当前页处理完成后,跳转到上一页returngoToPreviousPage(iframeDoc);}// 8. 主处理函数 - 处理指定数量的页面asyncfunctionprocessPages(){console.log('=== 说说批量删除脚本 ===');// 询问用户要删除的页面数量totalPagesToDelete=askPageCount();if(totalPagesToDelete===null){console.log('脚本已取消');return;}console.log(`目标: 删除${totalPagesToDelete}个页面的说说`);console.log('开始处理...');lethasMorePages=true;while(hasMorePages&&isProcessing&&pagesDeleted<totalPagesToDelete){console.log(`\n=== 开始处理第${pagesDeleted+1}个页面 ===`);// 处理当前页面hasMorePages=awaitprocessPage();if(hasMorePages&&pagesDeleted<totalPagesToDelete){console.log(`等待${delay/1000}秒,让新页面加载...`);awaitnewPromise(resolve=>setTimeout(resolve,delay*2));}}console.log('\n=== 处理完成 ===');console.log(`总共处理了${pagesDeleted}个页面`);console.log(`目标:${totalPagesToDelete}个页面`);if(pagesDeleted>=totalPagesToDelete){console.log('✓ 已完成指定数量的页面删除!');}else{console.log('⚠ 未完成所有指定页面,可能是没有更多页面了');}// 清理if(dialogObserver){dialogObserver.disconnect();}}// 9. 立即执行processPages();// 10. 添加控制函数到全局window.pauseDeletion=()=>{isProcessing=false;if(dialogObserver)dialogObserver.disconnect();console.log('已暂停');};window.resumeDeletion=()=>{isProcessing=true;console.log('已恢复,继续处理');processPages();};window.getProgress=()=>{return{pagesDeleted,totalPagesToDelete,remaining:totalPagesToDelete-pagesDeleted,progress:totalPagesToDelete>0?(pagesDeleted/totalPagesToDelete*100).toFixed(1):0};};window.showProgressInfo=()=>{constprogress=getProgress();console.log(`进度:${progress.pagesDeleted}/${progress.totalPagesToDelete}页面`);console.log(`剩余:${progress.remaining}个页面`);console.log(`完成:${progress.progress}%`);};})();

2.用法

先打开网页版qq空间,点击说说:

然后划到最下面,点最后一页说说:

按 F12 打开控制台,并选择 console 页面:

有些人应该第一次开这个控制台,所以会发现不让粘帖脚本代码 —— 会有个黄色的警告
有些人应该第一次开这个控制台,所以会发现不让粘帖脚本代码 —— 会有个黄色的警告
有些人应该第一次开这个控制台,所以会发现不让粘帖脚本代码 —— 会有个黄色的警告

在这里输入:

allow pasting

然后回车。
就可以粘贴脚本代码了。

粘贴脚本代码,并回车:

如果没错,会出现这个让你输入删除的页面数量的提示框。
它的规则是:从后往前删几页。

比如说,我们刚才在 171 页,那么我往前删 5 页,删到 160 多页
你就填 5,然后点击确定即可。

然后脚本就会自动开始运行:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/31 13:21:14

keil编译器下载v5.06环境下多任务调度器实现完整指南

在Keil MDK 5.06环境下构建轻量级多任务调度器&#xff1a;从零实现与实战优化当嵌入式系统“忙不过来”时&#xff0c;我们该怎么办&#xff1f;你有没有遇到过这样的场景&#xff1f;一个STM32项目里既要读传感器、又要处理串口命令、还得刷新LCD屏幕、偶尔还要闪一下LED做状…

作者头像 李华
网站建设 2026/3/15 12:23:28

私有化部署客户案例:某银行如何用TensorRT节省百万成本

某银行如何用TensorRT节省百万成本&#xff1a;私有化部署的推理优化实践 在金融系统中&#xff0c;一次交易请求背后的AI推理可能决定着千万级资金的安全。某大型商业银行的日均反欺诈检测调用量高达2亿次&#xff0c;任何毫秒级的延迟累积都会直接影响用户体验和风控有效性。…

作者头像 李华
网站建设 2026/3/21 1:49:16

jlink驱动Windows安装指南:从下载到识别完整流程

J-Link驱动Windows安装全攻略&#xff1a;从零开始&#xff0c;一次搞定设备识别与调试连接 你有没有遇到过这样的场景&#xff1f;新买了一块STM32开发板&#xff0c;兴冲冲打开Keil准备下载程序&#xff0c;结果点击“Debug”时弹出一串红字&#xff1a;“No J-Link found.”…

作者头像 李华
网站建设 2026/4/1 21:40:59

【UML】面向对象中类与类之间的关系详解

作为程序员&#xff0c;在学习或使用面向对象编程&#xff08;OOP&#xff09;时&#xff0c;类与类之间的关系是一个绕不开的话题。合理地建模类之间的关系&#xff0c;不仅能让代码更清晰&#xff0c;也能显著提升系统的可维护性和扩展性。 文章目录一、为什么要理解类之间的…

作者头像 李华
网站建设 2026/3/29 19:09:12

PWM控制蜂鸣器音调:小白也能懂的图解说明

蜂鸣器怎么“唱歌”&#xff1f;一张图看懂PWM如何控制音调你有没有想过&#xff0c;为什么家里的微波炉按下按钮会“嘀”一声&#xff0c;而智能门锁开锁却能播放一小段旋律&#xff1f;这些声音背后&#xff0c;其实藏着一个既简单又巧妙的技术——用PWM让蜂鸣器发出不同音调…

作者头像 李华
网站建设 2026/4/2 6:17:19

元宇宙虚拟人对话系统:低延迟交互背后的推理引擎

元宇宙虚拟人对话系统&#xff1a;低延迟交互背后的推理引擎 在一场元宇宙直播中&#xff0c;用户刚说完“你能帮我查下天气吗”&#xff0c;虚拟主播便立刻转头微笑、开口回应&#xff0c;语音自然流畅&#xff0c;口型与语调严丝合缝。整个过程毫无迟滞&#xff0c;仿佛对面真…

作者头像 李华