【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,然后点击确定即可。

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

相关推荐
程序员黑豆32 分钟前
鸿蒙应用开发:Refresh + List 下拉刷新组件使用教程
前端·华为·harmonyos
Hilaku33 分钟前
为什么大厂对前端算法要求极高?
前端·javascript·程序员
你可如意39 分钟前
从Promise开始,一篇让你彻底建立起JS的异步编程模型
javascript
Tkto1 小时前
我用 WebGL 从「画个点」一路画到「贪吃蛇」
前端
xiaobaoyu1 小时前
前端代码常用规范
前端
吃好睡好便好1 小时前
MATLAB中图像的读取、写入和显示
开发语言·图像处理·学习·计算机视觉·matlab
xiaobaoyu1 小时前
img,word,excel,pdf文件在线预览
前端
lichenyang4531 小时前
从 H5 到 HarmonyOS:我做了一个 npm + OHPM 双端发布的 ArkWeb JSBridge 框架
前端
用户84298142418101 小时前
AI时代,JS混淆加密还有用吗?
前端·javascript
xiaobaoyu1 小时前
如何理解前端项目中的绝对路径和相对路径
前端