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

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

一、脚本

1.内容

javascript 复制代码
// 一键批量删除说说(支持自定义页面数量)
(() => {
  const delay = 2000;
  let currentIndex = 0;
  let listItems = [];
  let dialogObserver = null;
  let isProcessing = true;
  let totalPagesToDelete = 0;
  let pagesDeleted = 0;
  
  // 1. 询问用户要删除的页面数量
  function askPageCount() {
    const input = prompt('请输入要连续删除的页面数量(请输入数字):', '5');
    
    if (input === null) {
      console.log('用户取消了操作');
      return null;
    }
    
    const pageCount = parseInt(input);
    
    if (isNaN(pageCount) || pageCount <= 0) {
      alert('请输入有效的正数!');
      return null;
    }
    
    return pageCount;
  }
  
  // 2. 自动查找iframe
  function findIframe() {
    // 尝试多种方式找到包含日志的iframe
    let iframe = document.querySelector('iframe.app_canvas_frame') || 
                 document.querySelector('iframe[src*="app.qzone"]') ||
                 document.querySelector('iframe[src*="qzone"]');
    
    if (!iframe) {
      // 遍历所有iframe,查找包含#msgList的
      const iframes = document.querySelectorAll('iframe');
      for (let frame of iframes) {
        try {
          const doc = frame.contentDocument;
          if (doc && doc.querySelector('#msgList')) {
            iframe = frame;
            break;
          }
        } catch(e) {
          // 跳过跨域iframe
        }
      }
    }
    
    if (!iframe) {
      console.log('未找到包含日志的iframe');
      return null;
    }
    
    try {
      return iframe.contentDocument || iframe.contentWindow.document;
    } catch(e) {
      console.log('无法访问iframe内容');
      return null;
    }
  }
  
  // 3. 自动点击确认对话框
  function setupDialogMonitor() {
    if (dialogObserver) return;
    
    dialogObserver = new MutationObserver((mutations) => {
      for (let mutation of mutations) {
        if (mutation.addedNodes.length > 0) {
          for (let node of mutation.addedNodes) {
            if (node.nodeType === 1 && 
                (node.matches('.qz_dialog_layer') || node.querySelector?.('.qz_dialog_layer'))) {
              console.log('检测到确认对话框');
              setTimeout(() => {
                const confirmBtn = document.querySelector('a[title="点击这里确认"]');
                if (confirmBtn) {
                  confirmBtn.click();
                  console.log('已点击确认按钮');
                }
              }, 300);
            }
          }
        }
      }
    });
    
    dialogObserver.observe(document.body, { childList: true, subtree: true });
  }
  
  // 4. 查找分页控件并跳转到上一页
  function goToPreviousPage(iframeDoc) {
    const pager = iframeDoc.querySelector('p.mod_pagenav_main');
    if (!pager) {
      console.log('未找到分页控件');
      return false;
    }
    
    // 获取pager的所有子元素(包括a和span)
    const children = Array.from(pager.children);
    
    if (children.length < 3) {
      console.log('分页元素不足,可能是最后一页');
      return false;
    }
    
    // 倒数第三个元素(因为倒数第一是"下一页",倒数第二是"当前页")
    const prevPageElement = children[children.length - 3];
    
    if (!prevPageElement || prevPageElement.tagName !== 'A') {
      console.log('未找到上一页链接');
      return false;
    }
    
    // 检查是否是可点击的链接(不是disabled状态)
    if (prevPageElement.classList.contains('mod_pagenav_disable') || 
        prevPageElement.style.pointerEvents === 'none') {
      console.log('上一页不可点击');
      return false;
    }
    
    console.log('正在跳转到上一页...');
    prevPageElement.click();
    return true;
  }
  
  // 5. 处理单条说说
  function processItem(li) {
    return new Promise((resolve) => {
      const trigger = li.querySelector('.dropdown-trigger');
      if (!trigger) {
        resolve(false);
        return;
      }
      
      // 滚动到元素
      li.scrollIntoView({ behavior: 'smooth', block: 'center' });
      
      setTimeout(() => {
        trigger.click();
        
        setTimeout(() => {
          const deleteBtn = 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. 显示进度信息
  function showProgress() {
    console.log(`进度: ${pagesDeleted}/${totalPagesToDelete} 页面`);
    console.log(`剩余: ${totalPagesToDelete - pagesDeleted} 个页面`);
  }
  
  // 7. 处理单个页面
  async function processPage() {
    const iframeDoc = findIframe();
    if (!iframeDoc) {
      console.log('无法访问iframe,停止处理');
      isProcessing = false;
      return false;
    }
    
    listItems = iframeDoc.querySelectorAll('#msgList li.feed.feed_private');
    
    if (listItems.length === 0) {
      console.log('当前页面没有说说,尝试跳转到上一页');
      
      // 尝试跳转到上一页
      if (goToPreviousPage(iframeDoc)) {
        console.log('等待新页面加载...');
        await new Promise(resolve => setTimeout(resolve, 3000));
        return true; // 继续处理
      } else {
        console.log('没有更多页面可处理');
        return false; // 停止处理
      }
    }
    
    console.log(`当前页面找到 ${listItems.length} 条说说,开始删除...`);
    
    // 启动对话框监视器
    setupDialogMonitor();
    
    // 处理当前页所有说说
    for (let i = 0; i < listItems.length; i++) {
      currentIndex = i;
      console.log(`处理第 ${i + 1}/${listItems.length} 条说说...`);
      
      const success = await processItem(listItems[i]);
      if (!success) {
        console.log(`第 ${i + 1} 条说说处理失败,跳过`);
      }
      
      // 如果不是最后一条,等待延迟
      if (i < listItems.length - 1) {
        console.log(`等待 ${delay/1000} 秒...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
    
    console.log('当前页面所有说说已删除!');
    pagesDeleted++;
    showProgress();
    
    // 等待一小段时间让页面稳定
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    // 检查是否已达到指定的页面数量
    if (pagesDeleted >= totalPagesToDelete) {
      console.log(`已达到指定的 ${totalPagesToDelete} 个页面,停止处理`);
      return false;
    }
    
    // 当前页处理完成后,跳转到上一页
    return goToPreviousPage(iframeDoc);
  }
  
  // 8. 主处理函数 - 处理指定数量的页面
  async function processPages() {
    console.log('=== 说说批量删除脚本 ===');
    
    // 询问用户要删除的页面数量
    totalPagesToDelete = askPageCount();
    
    if (totalPagesToDelete === null) {
      console.log('脚本已取消');
      return;
    }
    
    console.log(`目标: 删除 ${totalPagesToDelete} 个页面的说说`);
    console.log('开始处理...');
    
    let hasMorePages = true;
    
    while (hasMorePages && isProcessing && pagesDeleted < totalPagesToDelete) {
      console.log(`\n=== 开始处理第 ${pagesDeleted + 1} 个页面 ===`);
      
      // 处理当前页面
      hasMorePages = await processPage();
      
      if (hasMorePages && pagesDeleted < totalPagesToDelete) {
        console.log(`等待 ${delay/1000} 秒,让新页面加载...`);
        await new Promise(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 = () => {
    const progress = getProgress();
    console.log(`进度: ${progress.pagesDeleted}/${progress.totalPagesToDelete} 页面`);
    console.log(`剩余: ${progress.remaining} 个页面`);
    console.log(`完成: ${progress.progress}%`);
  };
})();

2.用法

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

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

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

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

在这里输入:

javascript 复制代码
allow pasting

然后回车。

就可以粘贴脚本代码了。

粘贴脚本代码,并回车:

如果没错,会出现这个让你输入删除的页面数量的提示框。

它的规则是:从后往前删几页。

比如说,我们刚才在 171 页,那么我往前删 5 页,删到 160 多页

你就填 5,然后点击确定即可。

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

相关推荐
进击的野人2 小时前
Vuex 详解:现代 Vue.js 应用的状态管理方案
前端·vue.js·前端框架
未知原色2 小时前
前端工程师转型AI的优势与挑战
前端·人工智能
鹏北海2 小时前
Single-SPA 学习总结
前端·javascript·微服务
想学后端的前端工程师2 小时前
【CSS高级技巧与动画实战指南:打造炫酷的用户体验】
前端·css·ux
沐知全栈开发2 小时前
Web 词汇表
开发语言
程芯带你刷C语言简单算法题2 小时前
Day37~求组合数
c语言·开发语言·学习·算法·c
程序员-周李斌2 小时前
transmittable-thread-local[线程池跨线程值传递]
java·开发语言·算法·散列表
范纹杉想快点毕业2 小时前
入门工程师指南:基于CRC校验的通信协议底层C语言实现
c语言·开发语言·mongodb
_码力全开_2 小时前
第一章 html5 第一节 HTML5入门基础
前端·javascript·css·html·css3·html5