news 2026/9/26 8:17:22

豆包网页版批量删除历史对话:三种技术路线与实操指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
豆包网页版批量删除历史对话:三种技术路线与实操指南

1. 为什么“批量删除历史对话”是个真需求

豆包网页版用久了,侧边栏的历史对话会像滚雪球一样越积越多。我自己的账号用了不到三个月,侧边栏就攒了四百多条记录,往下翻的时候浏览器明显卡顿,找一条上周的对话得滚动半天。更麻烦的是,有些对话涉及工作草稿、临时灵感、测试用的提示词,留着占地方,一条条删又太折磨人。

豆包官方在网页版里给每条对话提供了删除入口,但只支持单条操作。点开某条对话,找到菜单,点删除,再确认,一套流程下来少说五秒。四百条就是半个多小时,纯体力活。所以“批量删除历史对话”这个需求,本质上不是技术难题,而是效率工具缺失带来的痛点。

这篇文章面向三类人:一是豆包网页版的重度用户,历史记录已经多到影响使用;二是对浏览器脚本、前端调试感兴趣,想拿这个场景练手的开发者;三是单纯想搞清楚“网页版到底能不能批量删、怎么删才安全”的普通用户。我会把几种可行方案从原理到实操讲透,包括我自己踩过的坑和最终稳定跑通的流程。

需要先说明一点:豆包网页版的产品形态会更新,界面元素和接口路径可能变化。我下面讲的方法论和排查思路是通用的,具体的选择器、请求参数需要你根据当时的页面实际情况做调整。这也是为什么我不建议你直接抄一段脚本就跑,而是理解原理后自己适配。

2. 批量删除的三条技术路线与选型逻辑

2.1 路线一:模拟点击,最直观但最脆弱

最容易被想到的方案是用浏览器自动化工具,比如在控制台里写一段脚本,模拟用户点击每一条对话的删除按钮。思路很直接:找到侧边栏所有对话条目,遍历它们,对每一条执行“打开菜单→点击删除→确认”的动作序列。

这条路线的好处是不依赖任何接口知识,你看到什么就点什么,逻辑透明。但问题也很明显:豆包网页版的侧边栏是虚拟滚动或者懒加载的,一屏只渲染可见的十几条,你脚本跑的时候,没渲染出来的条目根本不在 DOM 里。你得先模拟滚动,等新条目加载出来再继续,节奏很难控制。而且每次删除后列表会重排,索引会错位,稍不注意就点错或者漏点。

我最早试的就是这条路,写了大概三十行脚本,跑起来删了七八条就开始乱,要么重复点同一条,要么跳过。调试成本很高,不适合非开发者。

2.2 路线二:直接调用删除接口,快且可控

真正高效的方案是绕过 UI,直接找到豆包网页版删除对话时调用的后端接口,然后用脚本批量发请求。原理是:你在页面上手动删一条对话,浏览器开发者工具的 Network 面板里会记录下这个请求,包括请求地址、方法、请求头、请求体。把这个请求的结构搞清楚,就可以用代码循环调用。

这条路线的好处是速度快、可控性强。一条请求几十毫秒,四百条对话理论上十几秒就能处理完。而且你可以先拉取对话列表,拿到所有对话 ID,再按 ID 逐个删除,不依赖页面渲染。

难点在于两点:一是要正确携带身份凭证,通常是 Cookie 或者请求头里的某个 token,这个从你已登录的浏览器里直接取就行;二是要搞清楚列表接口和删除接口的参数格式,不同版本可能不一样。

2.3 路线三:半自动辅助,折中但稳

如果你不想碰接口,又觉得纯手动太慢,还有一条折中路:写一个辅助脚本,帮你自动展开菜单、自动点击删除、自动确认,但滚动和加载由你手动控制。你滚一屏,脚本删一屏,删完你再滚下一屏。

这条路线的好处是风险低,因为操作节奏由人把控,不会因为页面没加载完就乱点。缺点是还是需要你参与,没法完全挂机。但对于历史记录不是特别多、或者对脚本不太放心的用户,这是最稳妥的选择。

下面这张表把三条路线做个对比,方便你按自己的情况选:

路线技术门槛速度稳定性适合人群
模拟点击中慢低想练手的前端新手
调用接口中高快高有开发经验、追求效率
半自动辅助低中高普通用户、求稳

我最终采用的是路线二,下面重点讲这条。路线三我会在实操部分给一个简化版脚本,供不想碰接口的读者使用。

3. 动手前的准备工作与关键参数获取

3.1 环境与工具清单

你不需要装任何额外软件,一台能正常登录豆包网页版的电脑、一个现代浏览器(Chrome 或 Edge 都行)就够了。核心工具是浏览器自带的开发者工具,按 F12 或者右键“检查”就能打开。

我建议你专门开一个浏览器窗口来做这件事,不要和其他重要标签混在一起,避免误操作。另外,操作前先把豆包网页版刷新一次,确保页面状态干净。

3.2 抓取删除请求的完整过程

这是整个方案最关键的一步。打开开发者工具,切到 Network 面板,勾选“Preserve log”(保留日志),过滤条件先不设,或者设成 Fetch/XHR,这样只看接口请求。

然后回到页面,手动删除一条不重要的历史对话。删完之后,Network 面板里会多出几条请求。你要找的是那条方法为 DELETE 或者 POST、路径里带有 conversation、chat、message 之类关键词的请求。点开它,重点看四个东西:

  • Request URL:完整的接口地址,注意里面的对话 ID 部分,那就是你要替换的变量。
  • Request Method:通常是 DELETE 或 POST。
  • Request Headers:重点看 Cookie、Authorization、以及可能的 x-* 自定义头。这些是身份凭证,缺一不可。
  • Request Payload:如果是 POST,看看请求体里带了什么参数,比如对话 ID、时间戳等。

把这条请求右键选择“Copy as cURL”,粘贴到文本编辑器里,你就能看到完整的请求结构。这一步做完,你手里就有了删除单条对话的“钥匙”。

3.3 找到对话列表接口

光有删除接口还不够,你需要知道要删哪些对话的 ID。所以还得找到拉取历史对话列表的接口。同样在 Network 面板里,刷新页面或者滚动侧边栏,观察新出现的请求。列表接口通常返回一个 JSON,里面包含对话的 ID、标题、创建时间等字段。

找到之后,同样用“Copy as cURL”把请求结构保存下来。这个接口一般支持分页参数,比如 offset、limit、cursor 之类。你需要搞清楚它的分页方式,才能把所有对话都拉全。

注意:抓包过程中不要泄露你的 Cookie 和 token 给任何人。这些凭证等同于你的登录态,别人拿到就能操作你的账号。文章里我只会用占位符演示,你自己操作时也要注意截图打码。

3.4 参数计算:分页拉取全部对话 ID

假设列表接口每页返回 20 条,你的账号有 400 条对话,那就需要拉 20 页。分页参数常见的有两种:一种是 offset/limit,offset 从 0 开始,每次加 20;另一种是 cursor,上一页返回一个 next_cursor,下一页带上它。

你需要先手动请求第一页,看看返回结构里有没有 total 字段或者 has_more 字段。如果有 total,直接算出总页数;如果有 has_more,就循环请求直到它为 false。这一步的逻辑不复杂,但必须做对,否则会漏删或者重复删。

我自己的账号当时是 437 条,列表接口每页 30 条,has_more 为 true 时继续。我写了个循环,把每页的对话 ID 收集到一个数组里,最后得到完整的 437 个 ID。这个过程大概花了五六秒。

4. 完整实操流程与核心代码实现

4.1 第一步:在控制台拉取全部对话 ID

打开豆包网页版,登录后按 F12 打开控制台(Console 面板)。把下面这段代码粘贴进去,注意把LIST_API_URL替换成你抓到的列表接口地址,把 headers 里的凭证替换成你自己的。

// 拉取全部对话 ID 的示例逻辑 const LIST_API_URL = 'https://你的豆包域名/api/conversation/list'; const headers = { 'Cookie': '你的完整Cookie', 'Authorization': '你的token', 'Content-Type': 'application/json' }; async function fetchAllConversationIds() { let allIds = []; let hasMore = true; let offset = 0; const limit = 30; while (hasMore) { const resp = await fetch(`${LIST_API_URL}?offset=${offset}&limit=${limit}`, { method: 'GET', headers: headers, credentials: 'include' }); const data = await resp.json(); const items = data.data?.list || data.list || []; items.forEach(item => allIds.push(item.id || item.conversation_id)); hasMore = data.data?.has_more ?? data.has_more ?? false; offset += limit; console.log(`已拉取 ${allIds.length} 条`); await new Promise(r => setTimeout(r, 300)); // 控制频率 } console.log('全部 ID:', allIds); return allIds; } fetchAllConversationIds();

这段代码的核心是循环请求列表接口,把每页的对话 ID 收集起来。await new Promise(r => setTimeout(r, 300))这行是故意加的延迟,避免请求太密集触发风控。我实测下来,300 毫秒的间隔比较稳,太快了偶尔会返回 429。

跑完之后,控制台会打印出所有对话 ID。你可以把它复制出来存一份,万一后面删错了还能对照。

4.2 第二步:批量发送删除请求

拿到 ID 数组后,接着写删除逻辑。同样在控制台里执行:

// 批量删除的示例逻辑 const DELETE_API_URL = 'https://你的豆包域名/api/conversation/delete'; const deleteHeaders = { 'Cookie': '你的完整Cookie', 'Authorization': '你的token', 'Content-Type': 'application/json' }; async function batchDelete(ids) { let success = 0; let failed = []; for (let i = 0; i < ids.length; i++) { const id = ids[i]; try { const resp = await fetch(DELETE_API_URL, { method: 'POST', headers: deleteHeaders, credentials: 'include', body: JSON.stringify({ conversation_id: id }) }); if (resp.ok) { success++; } else { failed.push({ id, status: resp.status }); } } catch (e) { failed.push({ id, error: e.message }); } if (i % 10 === 0) { console.log(`进度:${i + 1}/${ids.length},成功 ${success}`); } await new Promise(r => setTimeout(r, 200)); } console.log(`完成,成功 ${success} 条,失败 ${failed.length} 条`); console.log('失败列表:', failed); } // 把上一步拿到的 ID 数组传进来 batchDelete(allIds);

这里有几个细节值得说。第一,删除请求的方法和请求体格式必须和你抓包看到的一致,有的版本是 DELETE 方法加 query 参数,有的是 POST 加 JSON body,不能想当然。第二,延迟我设的是 200 毫秒,比拉取时更保守,因为删除是写操作,风控更敏感。第三,失败列表一定要打印出来,方便你事后补删。

我自己的 437 条对话,用这个脚本跑了大概两分半钟,成功 431 条,失败 6 条。失败的几条我单独重跑了一次就过了,估计是偶发的网络抖动。

4.3 第三步:验证删除结果

脚本跑完后,不要急着关页面。先刷新豆包网页版,看侧边栏的历史对话是不是清空了。如果还有残留,可能是列表接口有缓存,或者有些对话不在你拉取的范围内(比如归档的、置顶的)。

我遇到过一个情况:有十几条对话是“置顶”状态,列表接口默认不返回它们,所以脚本没删到。后来我手动取消置顶再跑一次就解决了。所以你在拉取 ID 之前,最好先确认一下有没有置顶对话,有的话先取消置顶。

另外,删除操作通常是软删除,服务端标记一下,前端不再展示。如果你发现删完刷新又出现了,可能是接口调用没真正生效,检查一下返回状态码是不是 200。

4.4 半自动辅助脚本(不想碰接口的看这里)

如果你不想折腾接口,这里给一个半自动方案。它的逻辑是:你手动滚动侧边栏,脚本自动帮你点删除。你只需要在控制台粘贴一次,然后滚动页面就行。

// 半自动辅助:自动点击删除按钮 setInterval(() => { // 找到所有还没删除的对话条目的菜单按钮 const menuButtons = document.querySelectorAll('[data-testid="conversation-more"]'); menuButtons.forEach(btn => { if (btn.dataset.processed) return; btn.dataset.processed = '1'; btn.click(); setTimeout(() => { const deleteBtn = document.querySelector('[data-testid="delete-conversation"]'); if (deleteBtn) deleteBtn.click(); setTimeout(() => { const confirmBtn = document.querySelector('[data-testid="confirm-delete"]'); if (confirmBtn) confirmBtn.click(); }, 200); }, 200); }); }, 1000);

这段代码里的选择器>

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

SoC低功耗唤醒失败排查:PLL已lock设备为何仍无响应

1. 一个让无数嵌入式工程师抓狂的深夜现场凌晨两点&#xff0c;示波器上 PLL 的 lock 信号稳稳拉高&#xff0c;时钟树看起来一切正常&#xff0c;电源管理寄存器读回来也显示各个电源域已经上电&#xff0c;可设备就是躺在那里一动不动&#xff0c;串口没有任何打印&#xff0…

作者头像 李华
网站建设 2026/9/26 8:14:05

VPet虚拟桌宠模拟器:从安装配置到MOD开发与性能调优全攻略

1. 为什么我要折腾一个桌面宠物 第一次接触 VPet 是在一个技术群里&#xff0c;有人发了一张截图&#xff1a;一只像素风格的小人坐在任务栏上&#xff0c;旁边还飘着一个状态面板&#xff0c;显示着“饥饿值”“心情值”“体力值”。当时我以为这只是个普通的桌面挂件&#xf…

作者头像 李华
网站建设 2026/9/26 8:13:08

AI钓鱼套件黑产化:MFA为何失效与防御升级指南

这一阵子&#xff0c;网络安全圈里到处都在转一条消息&#xff1a;AI钓鱼套件已经黑产化了&#xff0c;BlackForce、GhostFrame这些名字&#xff0c;从前几年还藏在黑产社区里的“小众技术品”&#xff0c;一下子被推到了大众面前。作为一个常年做企业安全建设和红蓝对抗的人&a…

作者头像 李华
网站建设 2026/9/26 8:12:50

三红主图指标源码详解:三信号共振确认底部区域

最近不少朋友在问三红主图这个指标&#xff0c;尤其是“寻底部区域”这个用法。市面上叫“三红”的指标不少&#xff0c;有麒麟三红、三步点金之类&#xff0c;但核心思路大同小异——用三个独立维度的信号同时转红&#xff0c;来确认底部区域而不是盲目猜底。今天把我自己整理…

作者头像 李华
网站建设 2026/9/26 8:12:39

XSS跨站脚本攻击原理、类型与防御实战指南

1. 从“网页弹窗”说起&#xff1a;XSS到底是什么很多人第一次接触XSS&#xff0c;是从某个群里收到一条链接开始的——“点开它&#xff0c;能偷你的cookie”。点开之后&#xff0c;网页弹了个窗&#xff0c;Cookie确实被发走了&#xff0c;然后你就“被下线”了。这其实就是X…

作者头像 李华
网站建设 2026/9/26 8:11:50

Notepad++高效文本处理实战指南:从入门到企业级应用

1. 为什么一个“记事本”值得你花45分钟认真对待Notepad 这个名字听起来像极了Windows自带的那个灰扑扑的记事本——但如果你真这么想&#xff0c;我劝你立刻关掉页面&#xff0c;去下载一个真正的Notepad&#xff0c;然后打开它&#xff0c;把系统自带记事本拖进回收站。这不是…

作者头像 李华