把 mufy 上所有角色的聊天记录一次性导出来,存成能长期保存、能当小说翻的文件。
mufy 自带的导出只能在存档列表里一条一条点。角色多、存档多的时候基本没法用。
不需要电脑。 装脚本 → 导出 → 转成电子书 → 读,整条链路在手机上就能闭环, iPhone 和安卓都有用户实际走通过。 很多人以为这是个"电脑工具"就直接关掉了,其实不是。
👉 手机用户直接看这一节:附:手机上全程走完 (iPhone 用 Safari + Userscripts,安卓用 X浏览器 / Via / 火狐+篡改猴,都有分步教程)
mufy 公告过迁移服务器会丢一部分聊天记录,已经有用户的早期记录在两条路上都取不回来了 (这个脚本和 mufy 官方自己的导出都拿不到)。 导出来放在自己硬盘上的那一份,才是不会变的那一份。
⚠️ 非官方工具,和 mufy 官方无关。它走的是网页自己在用的接口,官方改接口就可能失效。 只读你自己的账号数据。🔞 面向成年用户。请勿向未成年人传播本工具或站点地址。
- 📱 只有手机也能用(全程) —— 没有电脑照样能导、能读;很多人漏了这条
- 先读这一段,能省你很多时间 —— 这仓库里没有 App,先搞清楚要用什么
- 第一步:导出你的聊天记录(电脑上) —— 装插件 → 装脚本 → 开始导(新手从这儿开始;没出现按钮的看这一节里的 🚨 大红框)
- 第二步之 A:用网页阅读器翻看 —— 直接读 zip 不用解压,手机也能用;升级版阅读器的指路也在这一节
- 第二步之 B:转成电子书,在手机上读 —— EPUB,导进微信读书当小说翻
- 导出的东西长什么样 —— 解开压缩包是什么结构
- 顺带:把人设面具也导出来 —— 含「没订阅只导得出几个」的说明
- 你自己写的角色卡 —— 全字段明文+图片;也讲了官方引继码为什么不够
- 导进酒馆(SillyTavern / Tavo 之类) —— 含「能不能接着聊」要先知道的三件事
- 聊天记录不受这个限制(连"已经找不到的角色"都导得出来) —— 哪些拿得到、哪些拿不到
⚠️ 最重要的一件事:你现有的备份可能是缺的 —— 用别的办法导的备份,很可能少一块- 常见问题 —— 导不出、乱码、文件对不上号、报错看不懂、会不会被封号(不会,附一例真实误会),都在这儿
- 附:手机上全程走完(iPhone / 安卓,两边都有人走通) —— 只有手机也能用
- License
这个仓库里没有「App」。 点开 make-epub.py 或 mufy-batch-export.user.js 会看到一屏
代码——那是正常的,它们是「代码文件」,不是应用程序,点开只会看到文字。
要用它们,得让浏览器去跑(下面第一步会教)。
| 你想做什么 | 需要什么 | 能在手机上做吗 |
|---|---|---|
| 导出聊天记录 | 浏览器 + 一个能跑脚本的扩展 | ✅ 可以(见手机教程) |
| 导出人设面具 | 同上(v1.11 新增) | ✅ 可以 |
| 导出你自己写的角色卡 | 同上(v1.12 新增) | ✅ 可以 |
| 转成电子书(EPUB) | 同上,v1.10 起不用装 Python 了 | ✅ 可以 |
| 用网页阅读器翻看 | 浏览器 | ✅ 可以(手机上用「直接选 zip 文件」多选整包,别用「选择文件夹」) |
| 在手机上读电子书 | 微信读书 / 图书 / 静读天下 | ✅ 可以 |
一句话:全都能在手机上做。 有电脑就照下面的正文走(屏幕大、批量导几百个角色更稳); 只有手机就直接跳到 附:手机上全程走完, 那一节是从零开始的分步教程,iPhone 和安卓分开写。
📱 只有手机?这一节可以跳过 —— 直接看 附:手机上全程走完,那边是从零开始的分步教程。
用电脑打开 Chrome 或 Edge,安装 Tampermonkey(篡改猴):
点进去选你的浏览器,按提示装上。装完浏览器右上角会多一个灰黑色的图标。
装完还有一步,很多人卡在这儿:浏览器默认不允许扩展运行用户脚本。
- Chrome 138 及以上:地址栏输
chrome://extensions→ 找到 Tampermonkey → 点「详细信息」→ 打开「允许用户脚本」开关。- 更早的 Chrome:同一页右上角打开「开发者模式」。
- Edge:地址栏输
edge://extensions→ 左下角打开「开发人员模式」。没开这个开关的表现很迷惑人:脚本明明装上了、Tampermonkey 面板里也看得见, 但 mufy 页面左下角就是不出现那个「⬇ 批量导出」按钮。 一发现按钮不出来,先回来检查这一项。
点这个链接:
https://raw.githubusercontent.com/willwefind/mufy-batch-export/main/mufy-batch-export.user.js
Tampermonkey 会自动弹出一个安装页面,点 安装 就好。
如果没弹安装页、只看到一屏代码,说明 Tampermonkey 没装好或没启用。 那就手动来:点浏览器右上角的 Tampermonkey 图标 →「添加新脚本」→ 把那一屏代码全选复制粘进去 → 按
Ctrl+S保存。
🌏 那个链接打不开?显示「无法访问此页面 /
DNS_PROBE_FINISHED_NXDOMAIN」?不是你网址打错了,也不是篡改猴的问题,是你的网络连不上
raw.githubusercontent.com这个域名——它和 github.com 是两个域名, 经常一个通一个不通(能打开仓库首页、却打不开这个链接,就是这种情况)。 篡改猴这时会说「没有访问此页面的权限」,那只是因为当前页是个错误页,没脚本可装。绕开它,一分钟装好:
- 回到仓库首页(github.com 那个,你既然能看到这份说明就说明它是通的)
- 点开
mufy-batch-export.user.js这个文件- 代码区右上角有一排小按钮,点那个复制图标(把整份代码复制到剪贴板) ——
⚠️ 别点 Raw 和 Download,那两个还是会跳到打不开的那个域名- 点浏览器右上角的篡改猴图标 →「添加新脚本…」
- 把编辑器里自带的那几行全选删掉,粘贴,按
Ctrl+S保存- 回 mufy 页面刷新,左下角就有按钮了
另外也可以试试这个镜像地址(内容和上面那个链接一模一样,我们核对过字节数):
https://cdn.jsdelivr.net/gh/willwefind/mufy-batch-export@main/mufy-batch-export.user.js——⚠️ 但我们没法保证你的网络能通它,通不了就走上面那六步。
⚠️ 这样手动装的脚本不会自动更新(自动更新也要走那个域名)。 以后想升级,把上面六步再走一遍就行。
看你要什么,说清楚免得白折腾:
- 只导聊天记录 / EPUB:建议升,这几版修的都是真问题:
- v1.13:以前一个角色出错,整批就停在那儿,后面的角色一个都不会再试。 现在会跳过继续跑,结尾报清成功/失败。
- v1.14:面板底部多了「⬇ 手动保存」链接——万一自动下载没成功(有人遇到过 「显示导出完毕、下载列表里却没有文件」),点一下就能补存。同版还修了 「手动填角色 ID 时会漏掉那段没存档的对话」。
- v1.15:面具没导全时会明确告诉你少了几个,不再让你以为导全了。
- v1.16:打包时更省内存;一包特别大的时候会提前提醒你手机可能扛不住。
- v1.17:
.md加了 UTF-8 BOM,修掉安卓上「有的文件正常、有的中文乱码」。 - v1.18:导出期间请求「保持屏幕常亮」,减少手机上跑到一半被系统回收。
- v1.19:成批导时可以「从第几个开始」——中断后不用从头再来; 403 报错会说人话。
- v1.20:🔴 修了一个真 bug——某些角色名会被洗成同一个文件名, 导致「文件名是 A 卡、内容是 B 卡」。有大量角色的建议升级后重导一次。
- v1.21:新增「酒馆对话(.jsonl)」输出,可以把记录导进 SillyTavern。
- v1.22:一个文件都没产生时会直接说明白,不再照旧说「文件在下载目录里」; 网页阅读器的「隐藏我的发言」修好了(以前点了没反应)。
- v1.23:新增「每包最多多少段对话」——对话上百段、以前一导就崩的角色现在能导了。
- v1.24:没导完整的段会在结尾逐条列出是哪个角色、哪一天; 并且发现少拿到时会自动换种翻页方式重试,能多救回一类情况。
- v1.25:某个角色大到报
Invalid string length时不再整轮失败—— 完整备份会自动退让(去缩进 → 一段一个 JSON),报错也会告诉你该怎么办。 - v1.26:「没导完整」的提示改写——条数对不上不一定是没抓到, 也可能是 mufy 迁移丢过记录而总数没更新(已有用户查清一例)。
- v1.28:两件用户报上来的事—— ① 很久以前的存档导出来只有 1KB、里面只有几句话,现在会明确标出来 并告诉你怎么救(去 mufy 里把那个存档「载入」再重导,就能拿到全文); ② 同一份聊天记录被导了两遍(你载入过某个存档,它同时又成了「最后一次聊天」), 现在内容一字不差的两段会自动合并成一份,并在日志和目录里说清楚。
- v1.29:超大角色会赶在浏览器杀掉整个标签页之前先停下来,并直接告诉你
该把「每包最多多少段对话」填成几。以前是页面「啪」地变成一张白底报错页
(
Out of Memory),日志和提示全没了,根本不知道该怎么办。 - v1.30 / v1.31:一条对话都取不到的角色,以前会被整个跳过,现在会出一个包 (里面至少有开场白),并且照实告诉你是怎么回事—— 🔴 特别是这种:你明明聊过,但接口现在一条正文都给不出来。 以前这种角色连个文件都没有,你根本不会发现它「不见了」。
- v1.32:电子书改成从早到晚排。以前书的第一章是你最近聊的那段, 翻开第一页就懵——有用户以为「最前面的聊天记录消失了」,其实它在最后一章。 现在第一章就是最早那段,从头读到尾就是时间顺序。 (ZIP 不变,仍是「最新的在前」:那是备份,查最近的最方便。)
- 🔴 v1.33:一整段特别长(上千条)的对话,以前可能只导到一部分,而且一声不吭。 接口自报的总数本身就可能是被截过的(有用户拿 mufy 官方导出对过账: 同一段官方那边 2971 条,接口却说只有 1000 条)——两个数一样, 旧版就以为拿全了,连个警告都不会给。现在遇到可疑的整数会主动往后多翻几页, 翻出来的会在日志里写「往后又翻出 N 条」。 如果你有一整段上千条的对话,值得用这一版重导一次。
- 🎯 v1.34:接着上面那条再试一发——改成一次请求就要 2000 条。
⚠️ 已经实测过了:这一发也没能多拿到。 在那位用户那段对话上, 我们试过的三种要法(500×2 页/从第 3 页往后要/一次要 2000)都停在 1000。 这一发留着不删(代价只有一次请求,且只落在可疑的段上),但别指望它。 一整段上千条、又想要更早内容的,走 mufy 官方的引继码导出(那是另一条路)。 - 🔴🔴 v1.35(如果你有上千条的长对话,只升这一版就够):
换掉了「翻完了没有」的判据。 以前是「拿到的条数够了接口自报的总数就停」——
可那个总数会撒谎,于是同一个毛病换着长相咬了三次(说 1000 其实不止、
截在 1026 这种数上就漏掉……每修一次就再漏一种数字)。
现在不看总数,只看这一页装满了没有:满页就继续要下一页,
出现不满的一页才算到头。这个接口只有「第几页 / 每页几条」两个旋钮,
「一直要到给不满为止」在道理上就是穷尽,不会再有下一种漏法。
对普通对话反而更省(25 条的段第一页就没装满,立刻停);
只有长段会多问一页,而那一问正是关键的一问。
同版还加了长段体检:导出日志和
00_目录.md里会写明 「接口说 N 条 / 实际取到 M 条 / 最早一条是哪天」, 你自己就能判断有没有缺前面,不用再导第二遍来试。 - v1.36 / v1.37:面板上「输出方式」那四项每项都配了一句人话,选到哪个说哪个; 体量过大时的那段建议也改成看人下菜—— 已经填过分批的不会再被劝"填 20"(那是往回走), 导电子书的也不会再被劝去关一个在这条路上根本不存在的 JSON 开关。
- 🔴 v1.38:导出日志现在能往上翻了。 以前面板里的日志只保留最近 40 行—— 导几十上百个角色时,"哪几个档没导出来"那几行早就被后面的消息挤掉了, 不是滑不上去,是那些行真的没了;而且每来一行都会把你拽回底部, 正在往上看也会被打断。现在全部保留,并且只有你本来贴着底部时才自动跟随, 日志框也加高了(原来只有七八行)。
- 🔴🔴 v1.39:「文件名写的是 A 角色、点进去却是 B 角色」这个老 bug 补齐了最后一个口子。
v1.20 修的只是同一次导出之内;可两个「洗完文件名之后同名」的角色
分两次单独导时,防撞表已经清空了,第二个又会被浏览器存成
xxx (1), 名实再次错位(导电子书时最容易中:EPUB 的文件名为了书架好看连时间戳都不带)。 现在会记住"这个文件名归哪个角色",跨次也认得出来,撞上就自动补角色 ID 并在日志里说明。 v1.38 及以前导出的文件如果撞过名,建议重导一次。 - ✨ v1.39 还加了一项「当前角色 · 只要正在聊的这一段」:只导你此刻正开着的那一段, 不碰这个角色的其它存档 —— 用户提的,"我只想留当下这一段,不想把几十个老存档也导一遍"。
- 🔴🔴 v1.40(导着导着就不弹下载了、或者点手动保存没反应的,升这一版):
有用户报——前几个角色都正常弹下载,后面几个就不弹了,下载列表里只剩最早那两个,
而且点面板里的「⬇ 手动保存」也一点反应都没有。这其实是两件事:
- 前半段是浏览器的「自动下载多个文件」策略。 第一个文件是你点「开始导出」带出来的、 算你的操作;从第二个起就归这条策略管,而且拦得没有任何提示(安卓上最常见)。 现在脚本会在下第二个文件的当口就把这件事说明白:该点哪个「允许」、 被静默拦了去哪儿开、已经做好的怎么补存。
- 后半段是「手动保存」这条路本身也会被拦(我们原先写着"手动点浏览器基本不会拦", 这句话收回)。现在每个文件给三条出路,被拦的是哪个动作就换一个: ⬇ 存(老路)/📤 分享(走系统的分享面板,手机上最管用,能直接存进「文件」)/ ↗ 打开(在新标签页里打开它,绕开"下载"这个动作本身)。
- 🆘 v1.41(有角色从列表里整个消失了的,升这一版):
作者把角色卡设为私密之后,那个角色会从「聊过的角色」列表里消失,
连 mufy 网页上都打不开,脚本这边则表现为「共 0 条存档 → 0 个对话待抓取」。
在真账号上逐个接口探过之后确认:聊天记录一条都没少,丢的是"够得着它的钥匙"——
取卡的接口 500,而「最后聊的那一段」的线索和卡在同一个返回里,跟着一起没了。
新增范围「救回卡已消失的角色」:把浏览器历史里那条聊天页地址
(
?roleId=…&sessionId=…)整条粘进来,就能按段把正文抓回来, 并会顺手再问一次存档列表多救一段。详见这一节, 里面有各系统各浏览器怎么翻历史。 同版还修了一句错话:以前这种情况面板会说「没有会员时过期存档就看不到了」, 那是把人往错误方向带,现在照实说是卡取不到了。⚠️ 注意「删卡」和「私密」是两回事:删卡的角色还在列表里、照常导得全, 只是没有开场白;只有「私密」才需要救。那一节开头有对照表。 另外 v1.41 起,卡取不到但角色还在列表里时,文件名会用列表里那个名字, 不再平白变成一串字母数字。 - 🔴 v1.42(用 v1.41 的人请再更新一次):面板加了滚动条。 v1.41 那段救援说明比较长,把面板撑高了——而面板是钉在底边往上长的, 桌面端一直没有高度上限(以前只有窄屏那条规则里有),于是顶部整个顶出屏幕外, 又没有滚动,再也回不到上面。现在两边都限高并自己滚, 右上角的 ✕ 也钉住不再跟着滚走;同版把那段说明收短了些。
- 🔴 v1.43(要用救援功能的必须升这一版):「在历史记录里搜角色名」是错的,已收回。
实测:mufy 聊天页的标题全是站名、网址里只有两串 ID,没有任何地方带角色名,
所以历史里那些条目长得一模一样,搜名字搜不到、搜
roleId又分不出谁是谁。 → 改成不用你分辨:把历史里的 mufy 聊天页地址一股脑全粘进来, 脚本先拉一遍「聊过的角色」列表,还在列表里的自动挑掉并报出名字, 只救真正消失的那些。 - 🆕 v1.44:两件。
① 「全部已关注角色」多了一个勾:「连没聊过的也导(只有开场白)」。
关注了但从没聊过的角色没有任何对话记录(连
sessionId都不存在), 但开场白还挂在卡上,常有一两千字。默认不勾(多数人只要聊天记录); 勾上会给它们各出一个只装开场白的包。 ⏳ 卡还在才拿得到——作者一旦删卡或设为私密,开场白也跟着没了。 ② 仓库里新增find-keys-in-history.py和它的零基础教程: 直接读你电脑上的浏览器历史,把所有 mufy 聊天页的roleId+sessionId一次挖出来(因为 Chrome 的历史界面会把它们折叠得只剩几条,见上一节)。 - 🔵 v1.46:「多出来的那一段」终于有名字了。
你有 5 条存档、导出来却是 6 段——多出来的那段是你当前正在聊、还没按保存的对话
(一直都是故意导它的,否则最后没存档的结尾会整个丢掉),
但它以前在目录和阅读器里没有任何标识,标题还常被削成「/17:15」这种残句,
真有用户把它当成了一个不存在的幽灵存档。现在日志、
00_目录.md、阅读器三处都会点名 「🔵 你当前正在聊的对话(不是存档,还没按过保存)」。 同版修了它的排序:以前按「最后一条消息的时间」排,如果你最后聊天是 7/15、 8/8 才补存了个档,「8.8 存档」就会插到当前对话前面,看起来像顺序错乱—— 现在当前对话永远算最新(ZIP 里排最前,电子书里排最后)。 - 🔴 v1.45:角色列表的分页上限从 3000 提到 12000,而且撞到上限会喊出来。 以前一次只要 50 个、最多翻 60 页 ⇒ 只有 3000,并且翻到头就静默停下, 多出来的角色会被悄悄漏掉(有用户问到这个数才发现)。 现在一次要 200(mufy 那边的上限就是 200),同样 60 页 ⇒ 12000, 请求数还降到四分之一;真撞到上限会明确告诉你「后面的没读到」。
- (其余情况已经导好的文件不受影响,不用重导——除非你正被上面那个乱码问题困扰。)
- 想导人设面具:要,得到 v1.11 才有那一项。
- 想导你自己写的角色卡:要,得到 v1.12 才有那一项。
怎么升,取决于你当初是怎么装的:
-
点上面那个链接装的(推荐的装法):Tampermonkey 会自己检查更新,默认每天一次。 懒得等就手动催:点 Tampermonkey 图标 →「管理面板」→「已安装脚本」→ 右上角「检查更新」。
-
当初是自己复制粘贴装的:不会自动更新,得再走一遍上面那个链接重装一次 (或者把旧脚本内容整个替换成新的)。
-
iPhone / iPad(Safari + Userscripts):不会自动更新,但更新只要点两下—— 用 Safari 打开下面这个网址,页面上会出现一条 「Userscript Installed: Tap to re-install」,点它就覆盖成新版了。
https://raw.githubusercontent.com/willwefind/mufy-batch-export/main/mufy-batch-export.user.js
🚨 点之前先把页面下拉刷新一下(那个网址有几分钟缓存,不刷新可能装到的还是旧版)。 装完回 mufy 那个标签页刷新一次才生效 —— 和第一次装脚本时一样。
🔴 如果你是 2026-08-10 凌晨装的 v1.33,面板上会写着
v1.32——那是我们的显示错误, 不是没装上。 脚本本身就是新的(@version是对的),只是面板标题里那个数字忘了跟着改。 已经修好了,重新装一次面板就会显示当前真实的版本号(现在是v1.46)。 给踩到的人添麻烦了,抱歉。装完版本号还是旧的? 按这个顺序: ① 先把 Safari 完全关掉重开(从后台划掉,不是刷新页面); ② 还不行就把旧的那份删掉再装一次——脚本是一个真实文件, 在你当初指定给 Userscripts 的那个文件夹里(「文件」App 里找), 删掉那个
.user.js,再回 Safari 打开上面的网址点横幅装。⚠️ ᴀA 弹出的那个 Userscripts 面板是用来开关脚本的,点进去不一定能编辑—— 点不开很正常,别在那儿较劲,走上面「文件」App 那条。
装完在 Tampermonkey 面板里看一眼版本号是不是 1.46.0,或者打开导出面板,
标题右边会写着 v1.46。
这是目前最多人卡住的一步,而且十有八九不是脚本的问题。
Chrome 138 版本以后,浏览器默认不允许扩展运行用户脚本——这个开关是关着的, 装好 Tampermonkey、脚本也显示「已启用」,它依然一行都不会跑。 点开 Tampermonkey 图标时,如果看到一句「此脚本还未被执行」,基本就是它。
打开它(30 秒):
- 地址栏输入
chrome://extensions回车- 找到 Tampermonkey(篡改猴),点「详细信息」
- 往下找到「允许用户脚本」,打开
- 回到 mufy 页面刷新一次
- 旧一点的 Chrome:同一页右上角打开「开发者模式」。
- Edge:地址栏输
edge://extensions,左下角「开发人员模式」; 较新的 Edge 也改成了在扩展详情里开「允许用户脚本」,两处都看一眼。📌 以前明明能用,最近突然没按钮了? 多半也是这一项—— 浏览器大版本更新后这个开关可能被重置,脚本不会报错,就是安静地不跑了。
懒得折腾 / 上面弄完还是没有?用这条,它绕开插件,一定能用:
- 先确认你在 mufy 里是登录状态(能看到自己的角色列表)。没登录的话粘进去也只会 提示「续不上登录态」。
- 在 mufy 的页面上按 F12
- 上面会出现一排标签:欢迎 / 元素 / 控制台 / 源代码——点「控制台」 (英文版叫 Console,就是同一个)
- 看最下面那一行,开头有个
>,点一下它旁边的空白,光标会在那儿闪- 第一次用 Chrome 可能不让粘贴,要你先手打一句
allow pasting回车(只需一次)- 打开脚本地址 →
Ctrl+A全选 →Ctrl+C复制- 回到刚才
>那一行 →Ctrl+V粘贴 → 回车- 左下角出现「⬇ 批量导出」按钮,用法完全一样
💡 控制台里本来就飘着一堆黄的红的(网页自己的报错),不用管; 但如果满屏都是 401,说明你的登录过期了,先重新登录再来第 5 步。
代价只是关掉标签页就没了,下次再粘一遍。急着导的时候走这条最快。
- 打开 mufy,登录,随便进一个角色的聊天页
- 页面左下角会出现一个 「⬇ 批量导出」 按钮,点它
- 面板里选:
- 范围 → 想备份全部就选「全部聊过的角色」
- 输出方式 → 拿不准就用默认的「每段对话一个文件(打包成 ZIP)」(唯一带原始数据的); 只想当小说读就选「每个角色一本电子书(EPUB)」。 四个选项的区别见下面「「输出方式」那四个到底选哪个?」
- 点 开始导出,然后等着
导出好的文件会自动下载到你浏览器的下载文件夹里,每个角色一个 .zip(或一本 .epub)。
先记一句:这四个只决定"东西打包成什么样",不决定"导多少"。 导多少是上面那个「范围」管的。 想要几种就跑几遍,互不影响,也不会覆盖。
一句话对号入座:
| 你想干什么 | 选这个 |
|---|---|
| 把记录存起来,以后不怕丢 | 每段对话一个文件(ZIP) ← 默认,拿不准就选它 |
| 一口气从头读到尾 | 全部合并成一份 Markdown |
| 当小说躺着读 / 手机上读 | 每个角色一本电子书(EPUB) |
| 搬去酒馆(SillyTavern)接着聊 | 酒馆对话(.jsonl) |
① 每段对话一个文件(打包成 ZIP) —— 默认,也是唯一算得上"备份"的那个
- 出来是什么:每个角色一个压缩包。解开来:一段对话一个
.md、00_开场白.md、00_目录.md(索引,能点进每一篇),还有_原始数据.json(一字不改的原文)。 - 用什么打开:
.md用记事本 / Markdown 阅读器都行; 电脑上直接把整个文件夹丢给网页阅读器,不用解压。 - 谁该选它:所有人。这是唯一保留原始数据的输出,别的都是"给人看的成品"。
- 顺序:最新的在前(备份是拿来查的,最近那段放最前面最方便)。
② 全部合并成一份 Markdown —— 一个长文件,从头读到尾
- 出来是什么:一个角色一份
.md(不是所有角色挤进一个文件), 开场白和每段对话依次接下来。 - 和 ZIP 差在哪:少了
00_目录.md索引(合并版靠标题分节,用不着)。⚠️ 勾了「附带 JSON」的话,这条路是另外单独下一个.json,不打包在一起,别以为漏了。 - 谁该选它:想一路滑到底通读、或者想丢进别的软件全文搜索的人。
③ 每个角色一本电子书(EPUB) —— 成品书,最适合手机
- 出来是什么:一个角色一本
.epub,自带封面和目录,一段对话一章,开场白单独一章。 - 用什么打开:微信读书 / Apple Books / 静读天下 / 多看——翻页、书签、进度都是原生的。
- 代价:正文是清理过的(去掉
<think>、状态栏 HTML、给模型看的规则行), 不含原始数据。所以:想备份请另外再导一次 ZIP。 - 顺序:从早到晚(书是从第一页读起的,第一章就是你最早聊的那段)。
④ 酒馆对话(.jsonl) —— 只有要搬去酒馆才选
- 出来是什么:一段存档一个
.jsonl,外加一份00_导入说明.md。 - 怎么用:酒馆里建好这个角色的卡 → 选中它 → 对话列表 → 导入对话 → 选一个
.jsonl。 ⚠️ 不放开场白:酒馆的第一条消息来自角色卡自己的开场白,这里再塞一条会重复。- 谁该选它:不打算搬去酒馆的人,完全用不上这个。
📌 两个最容易踩的误会:
- 「全部合并」不是"把所有东西合成一个文件" —— 它是一个角色一份; 而且不包含人设面具和你自己的角色卡(那是「范围」里另外的选项,要单独再导一次)。
- ZIP 和 EPUB 的顺序是反的,这是故意的:一个给你查(新→旧),一个给你读(早→晚)。 同一段对话在两边的「第 N 段」编号因此不一样,别拿号码互相对,看日期最准。
💡 拿不准就用默认的 ZIP 先导一份(那是唯一有原始数据的), 想读得舒服再单独跑一次 EPUB。两次互不影响。
跑之前记得做这两件事,不然会白跑:
- 浏览器设置里把「下载前询问每个文件的保存位置」关掉 (地址栏输
chrome://settings/downloads)。不关的话,每个角色都会弹一次 「另存为」窗口,几百个角色就是几百个窗口。- 跑的时候别把这个标签页切到后台。 浏览器会给后台标签页降速,导出会卡住。
中途浏览器会问一次「是否允许下载多个文件」,点允许。
⚠️ 它也可能不问、直接一声不吭地拦掉(安卓上最常见), 症状是前一两个下来了、后面就再也不弹了。 遇到就去「网站设置 → 自动下载」把它设成允许,详见下面常见问题里的那一条。
打开这个网页,点「选择存档文件夹」,选中放那些 zip 的文件夹:
不用解压,它直接读 zip。左边是角色和章节,右边是正文。
📱 手机也能用,但请优先用「直接选 zip 文件(可多选)」那个按钮。
用它可以一次把所有角色的 zip 全选进来,一步到位。 上面那个「选择文件夹」在手机上也点得动(实测),只是手机的文件选择器 一次只能挑一个,几十上百个角色那样点会点到崩溃 —— 所以别走那条。
(界面是按大屏排的,手机上会挤一点;想读得更舒服就用 EPUB。)
- 分页读,不用一路往下滑:长存档会切成一页页,
←→翻页; 底部那个页码是可以直接填的——162 页的存档想去第 80 页,填个数字回车就到(新增); 右下角还有一键回顶 / 回底两颗按钮(键盘Home/End同样可以), 内容比一屏长才会出现(新增); 翻到本段最后一页再按一下,就自然进入下一段(像翻书那样连着)。 想回到原来那种一路滚的读法,把「分页」改成「滚动」就行;页的长短也能调。 - 会记住你读到哪:下次打开同一个角色,直接回到上次那一段那一页。
- 🔍 全文搜索(新增):顶栏「🔍 搜索」,在当前角色的所有段落(含开场白)里搜关键词, 结果标着「哪一段 · 第几页」,点一条直接跳过去、命中那条消息会闪两下提示你在哪。 不用再一页页翻着找某段对话。
- 🖍 划线与小注(新增):像读书一样——在正文里划选一段字,点冒出来的「🖍 标记这段」, 可以顺手写句小注(留空=只划线)。划过的地方会一直带着淡淡的高亮,点它能看小注; 顶栏「📒 批注」里能看这个角色的全部划线、点一条跳回原文、也在那里删。 划线记在浏览器本地(localStorage),换浏览器/清缓存会丢——重要的话记得截图。
- 每个角色各自记「读到哪」(修好了):以前只有一条全局记录, 开过别的角色就把上一个的位置顶掉了——现在按角色各存一份, 连页内滚到哪都记(关页面那一刻也会结账),下次打开自动回到原位。
- 🔖 书签(新增):读到哪了点顶栏「🔖 存书签」,之后左侧角色名旁会多一面小旗, 重新进阅读器点它一下就直接跳回那一段那一页。每个角色记一个,重复存就覆盖。 (和上一条的区别:那个是自动的、只记最近一个角色;书签是你亲手钉的、每个角色各一个。)
- 正序 / 倒序随手切(新增):顶栏两个开关各管各的—— 「目录」管左侧段的排列(ZIP 默认最近的段在上面,想从头读起就倒过来;开场白永远钉在最上); 「正文」管一段之内消息的顺序(默认从早到晚像读小说,倒过来就是最新的在最前)。 切目录顺序时会留在你正在读的那一段,不会把你甩走。
- 八套皮肤:白 / 豆沙绿 / 羊皮纸 / 冷灰蓝 / 昼 / 灰 / 夜 / 纯黑 (中间四套是按护眼调的:底色不用纯白、字色不用纯黑,明度差压在不刺眼的区间)。
- 十种字体,字号、行距、页宽都能调,设置会记住。 部分中文字体需要你自己系统里装了才会生效,没装就自动退到系统宋体,不影响阅读。
- 隐藏我的发言:RP 记录里你发的常常是
$指令,藏起来只剩角色的叙述,最像读小说 (⚠️ 这个按钮在旧版里点了没反应,已修——请重新下载一次阅读器网页) - 藏脚手架:卡里给模型看的「规则:…」「待生成」这类行,读小说时是噪音,默认藏起来。 现在会在标题下写明这一段藏了几行——以前它在大多数角色身上什么都不做, 你根本没法判断它有没有在工作。
- 只导入一次:第一次选完文件夹后它会记住内容,以后打开直接就是完整书架
你的存档不会上传到任何地方。 这是个纯前端网页,文件全程只在你自己电脑上读。
⚠️ 别选云盘目录(WPS 云盘 / OneDrive)。云盘里的文件是「占位文件」, 本地只有壳,浏览器读不到,会显示「一个 zip 都没有」。 先把文件夹复制到本地硬盘(比如 D 盘),再选那个副本。
老阅读器有了升级版——Our Dialogues,一间更完整的「私人阅览室」。 还是同一个思路(纯前端网页、直接读你本地的导出),但底子全面升级:
- 不止 Mufy:Mufy 的 ZIP、ChatGPT / Claude 的官方导出,能放进同一个书架一起读;
- 本地书库:聊天文字导入一次就存进浏览器本地,下次打开直接是完整书架;
- 书签、划线小注、全文搜索、阅读进度都在,另有收藏与标签、导出 EPUB / Markdown / 单文件 HTML;
- 配好的本地语音档案能挂在消息旁边直接听(可选,进阶玩法);
- 三套纸感主题、四种印刷风格,手机也能用。
在线版(打开就能用,里面有一键示例书库):https://willwefind.github.io/our-dialogues/ 仓库(README 是中文,附零基础教程):https://github.com/willwefind/our-dialogues
和这里的一切一样:纯前端、全本地,你的存档不会上传到任何地方。
上面这个老阅读器继续保留、继续可用,不下线——用顺手了的照旧。 升级版是另一个独立网页,两边互不影响,想试就开个新标签页。
v1.10 起不需要 Python 了。 在导出面板的「输出方式」里选 「每个角色一本电子书(EPUB)」,导出来的直接就是书,每个角色一本,自带封面和目录。
拿到 .epub 之后跳到下面的「传到手机」那一段就行。
已经导过一堆 zip、不想重导的,用下面的 Python 脚本把它们就地转成书。
用 Python 脚本转已有的 zip(点开)
这一步需要在电脑上装 Python。
https://www.python.org/downloads/
下载安装时,第一个页面底部的 Add Python to PATH 一定要勾上,然后一路下一步。
回到仓库首页,绿色的 Code 按钮 → Download ZIP → 解压到一个文件夹。
在解压出来的文件夹里新建一个叫 存档 的文件夹,把第一步导出的所有 .zip 放进去。
看起来应该是这样:
你解压出来的文件夹/
├── make-epub.py
├── 存档/
│ ├── mufy_角色A_20260807-0324.zip
│ ├── mufy_角色B_20260807-0324.zip
│ └── ...
在那个文件夹的地址栏里输入 cmd 按回车(会弹出一个黑色窗口),然后输入:
python make-epub.py
按回车,等它跑完。成品出现在旁边新出来的 EPUB 文件夹里,每个角色一本书。
只想先试几本?用
python make-epub.py --limit 3
对话上百段的角色要填「每包最多多少段」分批导,于是一个角色出好几个包 (文件名带「第几到第几段」)。想通读的话——
把这个角色的所有分批 zip 都放进 存档 文件夹,跑一次 python make-epub.py 就行。
它会自动认出它们是同一个角色的不同批次,按顺序接成一本完整的书。
- 认的不是文件名,是包里记着的「我是第几批 / 一共该有几段」,所以顺序不会乱;
- 少了哪一批它会当场喊出来(写明少了几段),不会闷声出一本残书;
- 开场白只在第一批里,合并后照样在书的最前面;
- 想回到旧行为(一个包一本)就加
--no-merge。
⚠️ 上面这条只对zip有效——它读的是包里的原始数据,而 EPUB 是成品书,那份数据不在书里。 手上只有几十本.epub也有救,见下面那条。
💡 其实多数人不用分批:那个格子是给「内存不够、一导就崩」准备的。 电脑上导通常留空就行,直接出一本完整的书。 真的导不动,先试取消勾选「附带 JSON 完整备份」(占一半以上体积),再考虑分批。
(分批导过的人才会碰上:一个角色导出来好几本,想拼成完整的一本再导进读书软件。)
能。(📌 这里以前写着"没法合",是把"我们的脚本合不了"说成了"没人合得了",已经改过来。)
.epub 说到底也是个压缩包,把几本的章节接起来在技术上没有障碍,
只是我们的 make-epub.py 不做这件事——它靠的是 zip 里那份原始数据,而成品书里没有。
三条路,按稳妥程度排:
- 重导一次 ZIP,再跑
make-epub.py(最稳,也是唯一能自动查漏的一条)。 聊天记录在 mufy 那边没动,重导不会丢东西,只是多花一次时间。 - 本地的电子书工具合(例如 Calibre 这类桌面软件,合并 EPUB 通常要装一个插件)。
好处是东西不出你的电脑。
⚠️ 我们没实测过,具体步骤看那个工具自己的说明。 - 在线的 EPUB 合并网站(有用户反馈这样可行,我们没实测)。 🔴 但请先想一件事:那等于把你的整本聊天记录传给一个陌生的服务器。 里面是什么你自己清楚。不能接受就走第 1、2 条。
- 合出来的书里,每章顶上那行「第 N / M 段」会每一批都从 1 重来。 EPUB 这条路的段号是批内编号(zip 那条才是跨批连续的),所以合完没法靠章节号自查。
- 要自查有没有漏批,看文件名。 分批导出的 EPUB 文件名带着「第 X-Y 段」,
按它排一遍:区间首尾要接得上(
第1-20段接第21-40段…), 最后一本的 Y 就是这个角色的总段数。中间断了就是少了一批。
把 .epub 文件传到手机(微信传给自己、网盘、数据线都行),然后:
- 微信读书:电脑上打开 https://weread.qq.com/ → 「传书到手机」→ 拖进去
- Apple Books / 静读天下 / 多看:直接用「用其他应用打开」选它
翻页、目录、书签、进度都是原生的,和读正经电子书一样。
每个角色一个 zip,解开来是这样:
00_开场白.md ← 角色卡自带的开场白
00_目录.md ← 索引,可点进每一篇
01_20260806-2352_闷热湿黏的梅雨夜 · 宴会厅.md
02_20260531-0237_我给这段存档写的备注.md ← 你写过备注的,用你的备注
03_20260531-0101_未存档_沉闷微雨的夏夜.md ← 你没按过保存的那段
_原始数据.json ← 完整原文备份
文件名是 序号_日期_线索。你写过备注的用备注;没写的自动取那段开场白的场景抬头。
每个文件的修改时间也是对应日期,资源管理器里能按时间排。
面具是账号级的一份清单,不挂在任何角色底下,所以走单独一条路: 面板里 范围 选「人设面具(全部)」,其余不用管,点开始导出。
一个面具一份 md,按面具编辑框里的六栏原样分节:
# 我给这个面具写的备注
- 面具 ID:12345678
- 创建时间:2026-01-02 15:04:05
- 导出时间:2026-08-07 23:01:02
---
## 备注
## 名称
## 性别
## 我的描述
## 我的喜好
## 指令六栏一栏不落,空的也留着写「(空)」——空着也是事实,删了以后就看不出原来有没有。
一次性打包成 mufy_人设面具_N个_日期.zip,里面还有 00_目录.md 和
_原始数据.json(接口原样返回,一字不改)。想一口气通读就把输出方式改成
「全部合并成一份 Markdown」。
「清理 think」对面具没有作用(面具本来就是纯文本设定), 「EPUB」对面具也无从谈起(没有对话可成章)——选了面具之后面板会自己把它们说明白。
有用户实测:未订阅的账号,面具只导得出现有的那几个,被隐藏的那些拿不到。
这不是脚本少翻了页——接口本身就只返回你当前有权看到的面具,脚本没有办法绕过。 (mufy 的会员权益里包含「无限人设面具」,退订之后超出额度的那些会被隐藏起来。)
v1.15 起脚本会把这件事直说:如果接口报的总数比实际拿到的多,日志里会出现一行红字,
导出包的 00_目录.md 开头也会写一句,告诉你少了几个。不会让你以为导全了。
💡 所以面具要趁还看得见的时候导。
⚠️ 但别把这条推广到聊天记录上——那是两回事,见下面一节。
范围选「我创建的角色卡(全部)」。一张卡一个文件夹:
00_目录.md
01_角色名/
卡片.md ← 全字段明文,分好节
卡片.json ← 接口原样返回,一字不改
头像.jpg ← 图是真下下来的,不是链接
封面.jpg
02_另一个角色/
...
卡片.md 里按你在创建页看到的栏目分节:角色介绍 / 人设 / 逆境处理 / 开场设计 /
小剧场 / 全局美化 / 情节设定 / 输出设定 / 样例对话与文风 / 资料库 / 物品栏 /
默认认知 / 厨子の厨艺分享 / 正则条目(正则一条一小节,匹配和替换各自成块)。
空的栏也留着写「(空)」。
因为那份 XML 不是存档,是搬家包。在一个有 4 张自制卡的真实账号上逐字段比对过 (SHA-256,不是肉眼看):
| 官方 XML 里 | |
|---|---|
| 人设 / 开场 / 输出设定 / 样例对话与文风 / 情节设定 / 作者的话 / 元信息 / 正则条目 | ✅ 明文,与接口逐字一致 |
| 小剧场、全局美化 | 🔒 加密(base64 解开是 {salt, iv, ciphertext}) |
| 角色图片 |
也就是说:官方那份正文相当老实,但你最花心血的美化代码在里面是密文—— 那两块往往是整张卡里最长的部分,都是卡主自己一个字一个字写的, 却在自己的导出文件里读不出来。图片也只是链接,哪天号没了或者站没了,图跟着没。
这个工具不碰那套加密,也不需要碰——接口本身返回的就是明文,直接落地即可。 它做的就两件事:把全部字段按人能读的样子写下来,把图真下下来。
想再拿一份官方引继码用来搬家,照旧去创建页导,两者不冲突。
输出方式选「酒馆对话(.jsonl,一段存档一个文件)」,
出来的 ZIP 里一段存档一个 .jsonl,外加一份 00_导入说明.md。
导法:在酒馆里建好这个角色的卡 → 选中它 → 对话列表 → 导入对话 → 选一个 .jsonl。
一个角色可以挂多个对话,想导几段就导几段。
一、文字肯定接得上。 导进去就能看到全部历史,直接往下打字,酒馆会接着往下写。
二、模型只看得到最近的一段。 酒馆会把最近能塞进上下文的消息发给模型, 更早的对你是存档、对它不是记忆。这点 mufy 也一样(所以才有「保存并开启新对话」)。 想让它记住早期的关键设定,用酒馆的总结 / 作者注释 / 世界书把它们沉淀下来。
三、角色不会一模一样。 mufy 里那个语气,是人设+小剧场+输出设定+正则 再加上 mufy 那边的模型一起长出来的。换到酒馆,模型和提示词拼装方式都变了, 就算人设一字不差贴过去,口吻也会变。 导入历史其实是最有效的"定调"手段(模型会照着已有对话模仿),但它是像,不是同一个。
| 聊天记录 | ✅ 就是这个功能 |
| 人设 / 开场 / 输出设定 / 样例对话 | ✅ 用「我创建的角色卡」导出的 卡片.md,照着重建卡片 |
| 正则条目 | 🟡 酒馆有 Regex 扩展、也是 JS 正则,能手工搬;但作用域字段两边对不上,要逐条判断 |
| 小剧场 / 全局美化 | ❌ 那是 mufy 的网页渲染层,酒馆没有对应物 |
没有放开场白:酒馆的第一条消息来自角色卡自己的开场白,这里再塞一条会重复。 开场白原文在 ZIP 输出里(
00_开场白.md)。
✅ SillyTavern 导入已实测走通:真机导入后,条数对、说话人不反、 开场白一次都没重复出现,可以接着往下聊。
⚠️ 手机上的 Tavo 等前端:它们的角色卡兼容 SillyTavern 规格, 但对话能不能直接吃这个.jsonl,没有实测过,请自己试一下。
💡 用
<details>搭的状态栏会被保留,而且在酒馆里会渲染成可折叠的块。 「清理 think / 状态栏 HTML」清掉的是<think>、注释、<style>/<script>以及divspanptable这类标签;<details>/<summary>不在清理名单里 —— 实测下来这样反而更好看,就没动它。
上面说的面具限制只适用于面具那种「按会员额度限量的功能」。聊天记录是另一回事:
有用户反馈,用这个工具导出了自己很久以前聊的第一个角色——那个角色在 mufy 里 她已经找不到了。这不是意外,是接口结构决定的:
- 角色列表走的是「你自己的互动历史」。
/api/characters/query_session一共就 9 个字段(characterId/lastInteracted/lastSessionId/lastDialogContent等), 一个「可见性 / 已删除 / 状态」字段都没有。它列的是"你跟谁聊过", 不是"现在还能搜到哪些角色"。所以作者把卡下架或删掉,它照样在你的列表里。 - 对话正文挂在你自己的 session 底下,按
sessionId + characterId取,是你的数据。 - 脚本会一路翻到底。mufy 的界面通常只让你看到最近那一截,翻不回三年前; 脚本把每一页都翻完(实测某账号 211 个聊过的角色全在)。
- 就算角色卡本身已经取不到了,脚本会退回用角色 ID 的前 8 位当名字继续导对话, 一条都不会少——只是文件名会变成一串字符而不是角色名。
✅ 这条不是推演,是撞上过:在一个真实账号上导全量时,有两个角色的压缩包 名字变成了一串字符;拿去 mufy 上核对,那两张卡确实已经被下架了。 而它们的聊天记录一条不少地导了出来。 (所以看到这种文件名不用慌,它恰恰说明脚本救回了一个你已经找不到的角色。)
一句话:「现在还能不能搜到这个角色」不影响导出——列表按你的互动历史来。
上面说的是角色。存档要分开讲,这两件事很容易混:
| 角色在 mufy 里搜不到了 / 被下架删卡 | ✅ 照样能导,列表按「你跟谁聊过」来 |
| 聊过但从没按过保存的最后一段 | ✅ 能导(这是脚本特意补的,文件名带 未存档_) |
| 历史存档过期了、界面上已经看不到 | ❌ 导不出来 |
为什么导不出:脚本拿的是 mufy 自己那个「存档列表」接口, 它只返回你账号当前有权看到的存档。界面上你看不到的,接口也不会给,脚本没有办法绕过。 没有会员时超期的存档就属于这一类。
多位用户实测过同一个结论:还能看到的(包括还没过期的历史存档)都导得出来, 已经看不见的导不出来。 这不是脚本坏了,是数据那边就没给。
💡 所以:想留住的对话,趁还看得见的时候导。 在 mufy 里按一下「保存并开启新对话」也能让那一段更稳。
v1.22 起,如果一轮跑完一个文件都没产生,面板会直接说明白 (而不是照旧说一句「文件在下载目录里」让你去下载夹里空找)。
(当然,这说的是 mufy 现在的行为。真正想留住的东西,导出来放在自己硬盘上才算数。)
先说结论:聊天记录八成还在,只是"门"没了。v1.41 起能把它救回来。
两种在接口上长得一样(取卡都是 500),但 mufy 对它们的处理不一样—— 这一栏是 2026-08-14 拿真账号上两种角色对比测出来的:
| 作者删了卡 | 作者把卡设为私密 | |
|---|---|---|
| 还在你的「聊过的角色」列表里吗 (脚本看到的那个列表) |
✅ 在,名字也还在 | ❌ 被摘掉了 |
| 能不能导 | ✅ 照常导,连没存过档的段都在 | ❌ 列表里都没有,根本轮不到 |
| 你会看到什么 | 一切正常,只是没有开场白 | 这个角色整个不见了 |
| 要不要救 | 不用 | 要,见下面 |
🔴 别用「在 mufy 里搜不搜得到」来分辨。 搜不搜得到取决于你有没有收藏过它 ——收藏过的,删了卡也还在你的收藏列表里搜得到;没收藏过的,本来就没有入口。 这和卡是删了还是私密没有关系。
📌 可靠的判据只有一个:照常导一遍,看结果里有没有它。
- 出包了(文件名可能是一串字母数字、而且没有开场白)→ 删卡,记录一条不少,不用管;
- 根本没有它,或日志写着「共 0 条存档 → 0 个对话待抓取」→ 私密,走下面的救援。
三件事一起发生:
| 取角色卡的接口 | 直接 500 Character not found |
| → 开场白 | 拿不到了 |
| → 🔴 「最后聊的那一段」的线索 | 和卡在同一个返回里,跟着一起没了 |
| 「聊过的角色」列表 | mufy 把它摘掉了——脚本列不到,你在 mufy 网页上也打不开了 |
(删卡只有第一、二行会发生:角色还在列表里,名字和「最后一段」的线索都由列表提供, 所以照样导得全。私密是四行全中,尤其最后两行,才把路堵死。)
于是一个没存过档的角色会变成「共 0 条存档 → 0 个对话待抓取」,看起来像是记录没了。
但记录没没。 实测 5 个这样的角色、共 7 段:只要拿得到那一段的「对话 ID」, 正文一条不少全都拿得回来(26 / 4 / 54 / 2 / 6 条,与半年前导的旧包逐段相同)。
mufy 的聊天页地址长这样——两把钥匙都在里面:
https://……/chat?roleId=xxxxxxxx-xxxx-…&sessionId=yyyyyyyy-yyyy-…
角色 ID ↑ 对话 ID ↑
只要历史记录里还留着这条地址,就能救。
⏳ 要趁早:浏览器历史一般只保留 90 天,清过历史、换过设备、换过浏览器就没了。 以前用本脚本导出过的人不用翻历史——旧压缩包里的
_原始数据.json,每一段都写着sessionId。
| 设备 / 浏览器 | 怎么打开历史 | 备注 |
|---|---|---|
| Windows Chrome / Edge | Ctrl + H |
或地址栏输 chrome://history(Edge 是 edge://history) |
| Mac Chrome / Edge | ⌘ + Y |
Safari 是 ⌘ + Y 也行 |
| Windows / Mac 火狐 | Ctrl+Shift+H(Mac ⌘+Shift+H) |
「资料库 → 历史」 |
| Mac Safari | 顶部菜单「历史 → 显示所有历史记录」 | |
| 安卓 Chrome / Edge | 右上角 ⋮ →「历史记录」 | |
| 安卓 Via / X浏览器 / 夸克等 | 底部或右上角菜单里的「历史」 | 各家位置不同,找「历史/记录」字样 |
| iPhone / iPad Safari | 底部 📖 书本图标 → 上方 🕐 时钟页签 | 这就是历史 |
| iPhone Chrome | 右下角 ⋯ →「历史记录」 |
进去之后,把那个角色的 roleId「整串」粘进搜索框。
🔴 两件事都别做:别搜角色名,也别只搜
roleId这个词。
- 搜角色名找不到:mufy 的聊天页标题全是站名(每一页一模一样), 网址里也只有两串 ID、没有名字。
- 只搜
roleId这个词,你会以为自己历史里就七八条——那是假象: Chrome 会把同一天 + 同一个标题的记录折叠成一行, 而 mufy 所有页面标题都一样,于是几百条被折成了「每天一条」。 实测:界面上显示 8 条,历史库里实际有 791 条。搜完整的那一串就能精确命中,不受折叠影响(至少要前 8 位)。 📌 这两条都是 2026-08-14 实测确认的。README 早前写过「搜角色名」和 「搜 roleId 把结果全粘进来」,都是错的,已收回。
那 roleId 从哪来? 两种:
- 别人发的清单里抄(有人会把「已经消失的角色」的 roleId 整理出来分享);
- 自己一次全挖出来:仓库里有个小工具
find-keys-in-history.py, 直接读你电脑上的浏览器历史文件,把所有 mufy 聊天页的roleId+sessionId一次性挖成 一个文本,全选粘进面板就行。零基础教程在这里:find-keys-in-history.md。 (只读你自己电脑上的文件,不联网、不上传。)
不确定哪一个才是消失的那个?不用确定。
把搜出来的地址一股脑全粘进去就行(几十条也没关系)。 脚本会先拉一遍你的「聊过的角色」列表,还在列表里的自动挑掉并报出名字, 只救真正消失的那些。所以你不需要分辨,它替你分辨。
怎么复制:
- 电脑上:右键那一条 →「复制链接地址」。
- 手机上:长按那一条,菜单里一般有「复制链接」; 实在不行就点开它——虽然对话打不开了,但地址栏里那串就是你要的, 从地址栏复制一样管用。
💡 一个角色可能有好几段对话 = 历史里好几条不同
sessionId的地址。 每一条都要,一段一条,不然只能救回其中一段。 (反正是全粘,多粘几条不吃亏。)
🔎 另外两个可能留着地址的地方:书签/收藏夹;以及你发给朋友、或者自己截过图的链接。
- 打开导出面板,范围选「救回卡已消失的角色(粘聊天页地址)」;
- 把刚才复制的地址整条粘进去,一行一条(可以粘好几条,也可以混着好几个角色);
- 点「开始导出」。
脚本会:按你给的对话 ID 逐段抓正文 → 顺手再问一次存档列表
(卡没了不代表存档也没了,实测 5 个里有 2 个还剩一条存档,能多救一段是一段)
→ 出包,并在 00_目录.md 里写明「这个角色的卡在 mufy 那边取不到了」。
⚠️ 只认地址里的roleId=/sessionId=。 光给两串裸 ID 是分不出谁是谁的, 猜错了只会白跑一趟,所以脚本宁可直接告诉你「没解析出 roleId」。 手写成roleId=xxx sessionId=yyy也认。
⚠️ 救不回来的情况:两把钥匙都没有(历史清了、也从没导出过)。 这时脚本变不出来——mufy 那边确实还存着,但没有任何入口能指到它。
📌 顺带修好的一句话:v1.40 及以前,碰到这种情况面板会说 「没有可导出的对话……没有会员时过期的历史存档就看不到了」—— 那句话把人往会员/过期那个方向带,是错的。v1.41 起它会照实说是卡取不到了, 并直接告诉你去翻历史。
如果你已经用别的办法导过 mufy,很可能少了两样东西。
mufy 的「存档」是你按了「保存并开启新对话」才产生的。只顺着存档列表导,会漏掉:
一、你聊过但从没按保存的对话。 实测在一个 200 多角色的账号上:102 个角色一条存档都没有, 但里面躺着 1356 条消息(最长的一个 112 条)。而且有存档的角色也照样漏—— 抽查 25 个,其中 24 个的最后一段没进过存档,又是 706 条。
二、角色卡自带的开场白。 它不在对话记录里,是挂在角色卡上的独立字段,实测一个角色的开场白有 1400 多字。 每个角色都有,一个都跑不掉。
v1.30 起,一条对话都取不到的角色也会出一个包(里面至少有
00_开场白.md)。 以前这类角色会被当成「没有可导出的对话」整个跳过,连个文件都没有—— 于是你根本不会发现它不见了。🔴 v1.31 又补了很重要的一层:说清楚到底是哪种情况。 有一种角色你明明聊过,但接口现在一条正文都给不出来(
total直接是 0、 也没有任何存档)。实测遇到过:mufy 那边还记着「最后互动是四月某天」, 内容却已经没了。 这种包的00_目录.md里会写明最后互动是哪天,并让你去 mufy 打开看一眼自己判断: 那边也是空的 = 记录确实没了;那边还看得到 = 是我们的问题,请报给我们。绝不会再把这种情况写成「你没聊过」——数据上它俩长得一样,但对人来说完全是两件事。
(唯一例外是「酒馆对话」那种输出:它本来就不放开场白,所以没有对话=真没东西可导, 面板会照实说跳过。)
这两样这个工具都会导出来(没存档的那段文件名带 未存档_,开场白是 00_开场白.md)。
我前两版都漏了,跑完还以为导全了。
顺带一提:脚本能捞的是「最后聊的那段」。一个角色如果有好几段都没存过档, 更早的那些谁也够不着。真正想留住的对话,还是在 mufy 里按一下 「保存并开启新对话」最稳。
Q:mufy 页面左下角根本没出现那个按钮?
八成是浏览器没允许扩展运行用户脚本——Chrome / Edge 默认是关的。
chrome://extensions → Tampermonkey →「详细信息」→ 打开「允许用户脚本」
(旧版 Chrome 是右上角的「开发者模式」,Edge 是「开发人员模式」)。
开完刷新 mufy 页面。脚本装没装好在 Tampermonkey 面板里能看见,
但那个开关是关的话,装好了也不会跑。
怎么确认就是它:点浏览器右上角的 Tampermonkey 图标,
如果那里写着「此脚本还未被执行」,就是这个开关没开
(它列的另外两个原因——脚本被禁用、URL 不匹配——都可以先不管:
脚本在面板里显示「已启用」就没被禁用;@match 覆盖 mufy 的所有页面,
在 /explore、/chat 上都一样,实测过)。
急着用就走控制台那条:在 mufy 页面按 F12 →
点「控制台」那个标签(英文版叫 Console)→ 点最下面 > 那一行 →
(必要时先手打 allow pasting 回车)→
把脚本
整段粘进去回车,按钮立刻出现,功能一模一样,只是关掉标签页就没了。
详细分步见上面「3. 开始导出」那个 🚨 框。
Q:点安装链接一直显示「无法访问此页面 / 检查是否有拼写错误」,篡改猴说「没有访问此页面的权限」?
网址没打错。 那个错误码(DNS_PROBE_FINISHED_NXDOMAIN)是域名解析失败——
你的网络连不上 raw.githubusercontent.com。它和 github.com 是两个不同的域名,
经常一个通一个不通,所以你能打开仓库首页、却打不开那个安装链接。
篡改猴那句「没有访问此页面的权限」是连带的:当前页是个错误页,本来就没有脚本可装。
解法:从 GitHub 的文件页直接复制代码,绕开那个域名—— 详细六步写在上面「2. 装脚本」那一节的 🌏 框里。 (关键一点:点复制图标,别点 Raw 或 Download,那两个还是会跳去打不开的域名。)
Q:iPhone / iPad 上我平常用的是 Chrome(或 Edge、夸克、QQ 浏览器),能装吗?
不能——iPhone 上只有 Safari 跑得了用户脚本。 iOS 版的 Chrome 不支持扩展 / 用户脚本(篡改猴没有 iOS Chrome 版),而且它也没有电脑上那条「F12 控制台粘一次」的兜底。 所以在 iPhone 上只有两条路:
- A:换 Safari —— App Store 装免费的 Userscripts,照下面「附:手机上全程走完」那一节走,全程手机就能闭环。
- B:用电脑导一次 —— 最省事,手机只负责读电子书。
📁 Safari 导出来的文件在「文件」App →「我的 iPhone / 下载项」。
Q:iPhone / iPad 上(Safari + Userscripts)左下角没有按钮?
(或者面板里写着 No matched userscripts)
Safari 上不用篡改猴,卡点也和电脑那套不一样。已确认的三个原因:
- 🚨 装完脚本之后,你没刷新那个页面。 最常见的一个,也最容易被跳过——
脚本只在页面加载的那一刻注入,你装脚本时开着的那个 mufy 标签页是"装之前"的,
它不会自己变出按钮来。回到 mufy 那个标签页刷新一次(下拉刷新或点地址栏重新进),
按钮就出来了。已有 iPhone 用户就卡在这一步,面板当时显示的正是
No matched userscripts。 - 🚨 你开着「无痕浏览」。 这个最迷惑人——脚本装得好好的、Userscripts 面板里 看得见而且是启用状态,就是不出按钮。换普通标签页(必要时把 Safari 完全关掉重开)。 已有用户就是这样,重开之后立刻就好了。
- 网站权限只给了「允许一次」。 换成「始终允许」,然后刷新页面。
先排除脚本自身的问题:ᴀA → Userscripts 打开面板,右上角总开关要是开的, 列表里「Mufy 批量导出聊天记录」要是亮白色(灰色 = 被停用)。 这两样对了就说明脚本没毛病,往上看那两条。
Q:以前一直好好的,最近突然没有按钮了?
同上那个开关。浏览器大版本更新之后它可能被重置,而且失败得很安静——
脚本不报错、Tampermonkey 里也照样显示「已启用」,就是不跑。
先去 chrome://extensions → Tampermonkey →「详细信息」看一眼「允许用户脚本」。
Q:装这个脚本会不会被封号?(有人遇到「Microsoft 帐户已锁定」)
✅ 先给结论:那一例已经查清楚了,不是封号。 是微软的风控锁定, 点一下「下一步」做个人机验证就解开了,跟这个脚本没有关系(原因是挂着加速器)。 细节在下面 📌 那一段。
先把两件事分开,它们经常被混在一起。
① 你的微软 / 谷歌账号:装脚本不会导致它被封。
装扩展、装用户脚本都是你自己浏览器里的本地行为——微软和谷歌的服务器收不到这个信号, 它们不知道你在哪个网站跑了什么脚本。反过来,mufy 也没有任何渠道去封你的微软或谷歌账号, 它能封的只有它自己这边的账号。
📌 真实的一例(2026-08-09):看着像封号,其实是一步就能解开的验证
一位安卓用户来问:「我想问问安卓手机到安装完脚本进mufy, 它检测到违反了协议给我 Microsoft 账号封了怎么办?」
拿到截图之后看明白了:那是微软的 「帐户已锁定」 页(
account.live.com), 写着「我们检测到违反 Microsoft 服务协议 的活动,并且锁定了你的帐户。 你只需在下一步中完成人机验证。」不是封号,是微软的风控锁定,点「下一步」过一次人机验证就能解开, 用不着申诉,也不用等。
两个最容易看错的地方:
- 那句「检测到违反了协议」是微软说的,说的是微软自己的服务协议, 不是 mufy 说你违反了 mufy 的协议——mufy 也没有权限去锁一个微软账号。
- 原因是加速器,这位用户自己找到的:他上浏览器和 mufy 时一直挂着加速器。 挂代理上网时微软账号还登着,是触发这种锁定最常见的情形(微软看到一个陌生的、 很多人共用的 IP 在登你的账号)。
解锁之前先把加速器关掉,用你平常那条网络去做人机验证,否则容易解开又被锁。 想少挨这一下:用一个不登微软账号的浏览器去开 mufy,或者给账号补一个手机验证方式。
万一遇到的是真的登不回去(不是这种一步可解的锁定),入口也在微软那边: 账户恢复表单 https://account.live.com/acsr。mufy 和这个工具都插不上手。
② 你的 mufy 账号:不能替它打包票,但到目前为止没有人报告过。
脚本用的是你已经登录的身份,调的是 mufy 网页自己就在调的那几个接口 (就是你在页面里往上翻聊天记录时会发出的那些请求),只读你自己账号里的东西, 全程只读、不写,请求之间留了 120–300ms 间隔、撞上限流会退避重试。 到现在为止,服务器那边唯一出现过的反应是临时 429 限流 (见下面那条,等一会儿自己就好,不伤记录、也不是封号)。
但 mufy 的用户协议怎么判是他们说了算,我不能替他们保证。不放心的话:少量分批导、 别开着加速器导、导完就把脚本关掉;或者干脆用 mufy 官方的引继码导出 (正文是全的,代价是小剧场和全局美化那部分是加密的、图片只有链接)。
怎么分清被封的到底是哪个账号:打开 outlook.com / gmail 看能不能正常收信。 收得到 → 是 mufy 那边(走 mufy 客服申诉);收不到 → 是邮箱账号那边,跟 mufy 无关。
Q:那个「⬇ 批量导出」悬浮按钮挡住了 mufy 的按键,怎么办? 更新到 v1.9。手机/窄屏下按钮会自动抬到底部导航上方,不再压住首页键。 按钮右上角有个 ✕,点一下当次收起(刷新页面就回来)。
Q:怎么彻底关掉这个脚本? 点浏览器右上角的 Tampermonkey 图标,把「Mufy 批量导出聊天记录」的开关关掉就行。 想再用的时候打开开关、刷新页面。 (如果你是用控制台粘贴的方式装的,关掉标签页就没了。)
Q:我明明只有 5 条存档,怎么导出来 6 段?多出来的那段是什么?
多出来的是「你当前正在聊、还没按过保存」的那一段。 它不是存档, 但一直都是故意连它一起导的——不导的话,你最后没存档的结尾会整个丢掉 (实测有账号 102 个角色零存档、里面躺着 1356 条消息,全靠这条路捞回来)。
v1.46 起它在日志、00_目录.md 和阅读器里都会标明
「🔵 你当前正在聊的对话(不是存档,还没按过保存)」,并且永远排在最前
(它就是"现在")。
Q:我有一段对话上万轮,这工具扛得住吗? 扛得住。合成了一段 1 万轮 / 2 万条消息 的对话做过全链路实测: 导出 40 次请求全部抓到、0 重复 0 遗漏;转成的 EPUB 导进微信读书能正常打开和跳目录; 用网页阅读器打开那一章也不卡。不需要你做任何特殊处理。
Q:手机上点 make-epub.py / mufy-reader.html 只看到一堆代码?
正常,它们是代码文件不是 App。make-epub.py 要电脑上的 Python。
网页阅读器手机上能用——用「直接选 zip 文件」那个按钮,可以一次多选整包
(「选择文件夹」在手机上一次只挑得了一个文件,别走那条)。
导出和转电子书现在手机上也能做,见下面的手机教程。
Q:手机上能全程走完吗? 能,两个平台都有人走通了。iPhone(Safari + Userscripts)已实测走完全程: 装脚本 → 导出 → 出 EPUB → 微信读书打开。安卓用自带脚本功能的浏览器 (X浏览器 / Via)或火狐 + Tampermonkey,已有安卓用户照最后一节的教程走通。
「网页阅读器」手机上也能用,用「直接选 zip 文件」那个按钮、一次多选整包 (「选择文件夹」在手机上一次只挑得了一个文件,几十个角色会点到崩溃)。 界面按大屏排的,手机上会挤一点;想读得舒服还是 EPUB,本来也更像读书。
Q:点仓库里的 html 链接为什么显示的是代码? GitHub 的 raw 地址会把网页文件当纯文本发,电脑手机都一样。 要用阅读器请点上面那个 github.io 的地址;想下载文件就点文件页右上角的 Download raw file。
Q:某个角色报 Invalid string length,整个导出失败、面板里连下载链接都没有?
这不是网络问题,也不是内存慢慢耗尽——是这个角色大到让脚本拼出了一个
超过 JS 语言上限的字符串(引擎大约到 5 亿字符就直接报这个错)。
最容易撞上限的是 _原始数据.json:它把整个角色序列化成一个字符串,缩进还让体积接近翻倍。
怎么办(按顺序):
- 面板上「每包最多多少段对话」填 20,再导一次。分批之后每一批都远在上限以下。
- 还不行填 10。
- 或者先取消勾选「附带 JSON 完整备份」,只要 Markdown。
v1.25 起脚本自己也会退让:那份完整备份太大时,先去掉缩进重试;还不行就
改成一段一个 JSON 文件放进 _原始数据/ 文件夹里——Markdown 正文一篇都不会少。
报错时面板也会直接告诉你上面这几步,而不是只甩一句英文。
Q:电子书导出成功了,但导进微信读书时卡在某个百分比失败?
多半是某一章太大(这个角色的单段对话特别长)。同样用「每包最多多少段对话」 分批导 —— 分批模式下 EPUB 也会跟着分成几本小书,每本都好啃得多。
Q:整个页面崩了,显示「此页存在问题 / 错误代码:Out of Memory」?
这跟下面那条是同一个病,但要单独说一句:这个页面是浏览器弹的,不是脚本弹的。 整个标签页的进程被系统杀掉了,所以脚本的日志、面板、连它本来想告诉你的 「内存不够,请填分批」那句话,全都跟着没了——你只看到一个白页。
照下面那条做(填「每包最多多少段对话」)就行,只是别指望脚本会先提醒你。
v1.29 起脚本会赶在浏览器动手之前先停下来:一批攥了太多字就主动报错、 并直接告诉你该填多少,至少日志还在、别的角色还能接着导。
Q:对话特别多的角色导不出来,报 out of memory / 页面直接崩了?
填「每包最多多少段对话」,这是最有效的一招。 面板上那个输入框,填 20 试试。
每轮都粘了很长的长期记忆/世界书的,20 还不够,填 5 甚至 2。 决定成败的不是段数,是总字数。有用户一万轮、178 段,而且每一轮都手工粘了 几万字的长期记忆——这种一段就顶别人几十段,卡在第 40 段左右整个页面就崩了。 (和长期记忆是什么格式无关:HTML 也好、纯文本也好,脚本只是原样搬运, 不解析、不渲染,只有体量本身要紧。)
为什么有用:以前是把这个角色所有段的对话全抓进内存、再打成一个包。 上百段、每轮还带着长期记忆的角色,光这一步就能把浏览器撑爆 (有人一万轮 / 178 段,电脑上都 out of memory;也有人 iPad 上 170 档约 500MB 直接崩)。
填了之后改成一批一批地抓、抓完打包就放掉,内存峰值只跟一批有关,和总量无关。 代价是同一个角色会出好几个包,文件名带「第几到第几段」,放同一个文件夹里就是完整的。
分批和不分批导出来的内容完全一样——这不是估计:拿一个 53 段的真实角色两种模式各导一次, 篇目数、文件名、每一篇的正文逐字比对 0 处差异,总字数都是 1,744,509。 段号也是跨批连续的(01…53),不会因为分批而错乱。
这一招治不了什么(两条,都是用户真撞上的):
- 切不开"一整段特别长"。 那个格子切的是段数,不是段里的条数。 一个角色要是本来就只有一两段、而那一段有上千条,填 1 也已经到底了, 再调小没有意义。这种只能用电脑导(桌面浏览器的内存额度宽得多)。
- 导电子书时,取消勾选「附带 JSON 完整备份」是没用的 —— EPUB 那条路本来就不产出 JSON。(v1.37 起提示语会自己认这一点,不再瞎劝。)
- mufy 那边看不到的存档(见上面那条)——那是数据就没有,不是内存问题。
Q:脚本说"已导出",下载列表里却找不到文件?
v1.14 起面板底部会留一排「⬇ 手动保存」链接(最近生成的几个文件), 直接点那个链接多半就能把文件存下来。
先按这个顺序确认是哪一环:
- 日志里有没有
⬇ 文件名 大小这一行? 有 = 文件已经做好了,是浏览器没收下(往下看第 2、3 条); 没有 = 没走到下载那步,日志里应该有别的提示。 - 地址栏最右边有没有一个"下载被阻止"的小图标? 这个提示很容易被忽略。
点它选允许,或去
chrome://settings/content/automaticDownloads把 mufy 加进允许列表。 - 下载目录还在吗? 如果之前设成了外置存储 / 云盘目录而现在不可用, 下载会失败得很安静。换回默认目录再试。
早期版本(v1.13 及以前)在下载后 8 秒就注销 blob 链接,文件大或者机器慢的时候 有可能让下载失败。v1.14 去掉了这个定时注销。
Q:前几个角色都弹了下载,后面几个就不弹了?(安卓上最常见)
这是浏览器的「自动下载多个文件」策略,不是脚本停了。
第一个文件是你点「开始导出」直接带出来的,算你本人的操作; 从第二个文件起就归这条策略管——浏览器要么弹一次 「是否允许 xxx 下载多个文件」,要么一声不吭地拦掉。 被拦的时候没有任何提示,所以看起来就像"导着导着就不弹了"。
怎么开:
- 安卓 Chrome / Edge:点地址栏左边那个锁(或 ⓘ)图标 →「网站设置」→
「自动下载」→ 改成「允许」。也可以在地址栏输
chrome://settings/content/automaticDownloads直接加白名单。 - 其它安卓浏览器(X浏览器 / Via / 夸克 / 华为 / 小米等): 在设置里找「下载」相关的项,把"每次询问 / 限制批量下载"关掉。
- 电脑 Chrome / Edge:同上,地址栏最右边通常还会出现一个带红叉的下载小图标, 点它选允许。
改完重导一次就都下来了。已经做好的那几个,用面板底下那排链接补存也行。
v1.40 起,脚本会在下第二个文件的当口就提醒你这件事,不用等到导完才发现少了一半。
Q:点「⬇ 手动保存」也一点反应都没有?
先说定心的一句:面板底下能看到那排链接,就说明文件已经做出来了, 聊天记录没丢,卡的只是"存到手机/硬盘里"这最后一步。
📌 这里原先写着"手动点属于用户操作,浏览器基本不会拦"—— 已经有用户遇到点了完全没反应的情况,那句话收回。
v1.40 起每个文件有三条出路,被拦的是哪个动作就换一个:
| 它是什么 | 什么时候用 | |
|---|---|---|
| ⬇ 存 | 老路(浏览器下载) | 默认先点这个 |
| 📤 分享 | 走系统的分享面板 | 手机上最管用:能直接存进「文件」,或者发给自己(微信/QQ 传文件助手)。只有支持的浏览器才会出现这个按钮 |
| ↗ 打开 | 在新标签页里打开它 | 前两个都不行时的退路。 |
三个都点了没反应,那就是这个浏览器不给下载,换一个再导一次:
- 是不是在 App 内置的浏览器里?(从微信 / QQ / 小红书 / 抖音里点开的网页) 这类内置浏览器基本不给下载文件,点了就是毫无反应。 用手机上正经的浏览器打开 mufy 重导一次。
- 安卓:长按那个「⬇ 手动保存」链接,看有没有「下载链接 / 保存链接」,有就点它。
- iPhone:很可能其实已经存下去了,只是没弹窗。 去「文件」App →「我的 iPhone / 下载项」翻一下。
- 电脑:装了迅雷 / IDM 这类下载器扩展吗? 它们会把下载抢过去,而这种"内存里现做的文件"它们接不住, 表现就是点了一片安静。先临时停用再点一次。
- 电脑:按
Ctrl+J打开下载页,看有没有一条"已阻止 / 失败"的记录——有的话原因就写在那儿。 - 都不行就换个浏览器重导(电脑上 Chrome 或火狐 + 篡改猴最规矩)。 文件是当场生成的,重导不会丢东西,只是多花一次时间。
Q:导完之后页面自己刷新了一下,然后没有文件?
那不是刷新,是这个标签页被系统回收后重载了——多半是内存不够。 一个存档特别多的角色(有人遇到过 352 段)打包时要在内存里同时放下正文、 压缩产物和那份 JSON,手机浏览器(Safari 尤其)很容易顶不住。 页面一重载,生成好的文件跟着没,连「⬇ 手动保存」也救不回来。
三个办法,从省事到彻底:
- **取消勾选「附带 JSON 完整备份」**再导一次。那份通常占一半以上体量。
- 换成「每个角色一本电子书(EPUB)」,正文清理过,比 ZIP 小不少。
- 用电脑导这个角色。 桌面浏览器的内存额度宽得多,这是最稳的。
v1.16 起,体量特别大的时候面板会提前提醒你,不用等它崩了才知道。
Q:导出来的文件,有的正常有的是乱码?(安卓上常见)
不是文件坏了,是看它的那个 App 猜错了编码。
导出的 .md 是 UTF-8。安卓上不少文本 / Markdown 阅读器会自己猜编码,
猜成 GBK 的话中文就全成乱码。猜得准不准跟文件内容有关,
所以会出现「同一批导出,有的正常有的乱码」这种怪事。
v1.17 起,所有 .md 都带上了 UTF-8 BOM(一个看不见的标记,明着告诉阅读器别猜)。
更新到 v1.17 重导一次就好了。
已经导出来的旧文件也能救,不用重导:换个能手动指定编码的 App 打开, 把编码设成 UTF-8 就正常了(比如 QuickEdit、Markor、或者电脑上的记事本 / VS Code)。
.json和 EPUB 故意没加 BOM——JSON 带 BOM 会让程序解析直接报错, 电子书阅读器也不需要。
Q:手机上导「全部角色」,息屏几次就被踢出去了,连已经下载好的也不见了?
两件事,分开看。
被踢出去:手机息屏或切到别的 App 之后,系统会回收后台的网页,导出当场断。 v1.18 起脚本会在导出期间请求「保持屏幕常亮」,能挡住屏幕自动熄灭; 但挡不住你手动锁屏或切走,那两种情况下系统仍会收回。 所以手机上导大批量时:别锁屏、别切 App,把手机放着让它跑完。
已经下载好的也不见了:先别急着重导,很可能还在。
不少安卓浏览器重启之后会清空它自己那个下载列表,但文件还在手机里。
用系统自带的「文件」App 去 内部存储 / Download 翻一下,八成都在那儿。
真的没有的话,那是它们还没写完就被中断了——只能重导那几个。
Q:安卓上导完了,浏览器的「下载」列表里却是空的 / 找不到文件?(X浏览器实测)
浏览器的下载记录和手机里的文件是两回事。 有用户在 X浏览器 上导完,
面板里明明写着 mufy_xxx_2026xxxx.zip 0.01 MB,而浏览器的 Downloads 是「No record」——
这类浏览器对网页内生成的文件经常压根不记这一笔,但文件是写下去了。
按这个顺序找,一分钟内能定:
- 就在那个下载页上换个标签。 X浏览器的下载界面顶上有
Directory/Downloads/Clean三个标签 —— 你看的是Downloads(空的),点左边那个Directory,那是文件夹视图,多半就在里面。 - 用手机自带的「文件管理」App(最靠谱):去
内部存储 / Download,按时间倒序; 找不到就搜mufy_或.zip。 - 还是没有,就点面板里那个「⬇ 手动保存」链接——它就是为这种情况留的,
点一下会重新触发保存;点了没反应就用它旁边的「📤 分享」(v1.40 起有,
走系统分享面板,安卓上这条最管用),详见上面那条
《点「⬇ 手动保存」也一点反应都没有?》。
⚠️ 这排链接关掉面板再打开还在(📌 早前这里写着"关了就没了",是错的), 但刷新或关掉 mufy 这个页面就真没了——那时只能重导。
💡 文件只有几 KB /
0.01 MB是正常的:只聊过一两轮的角色本来就这么小,不是没导全。 想确认内容,解开看00_目录.md就行。
⚠️ X浏览器这条路一直别扭的话,换 Via 浏览器(同样自带脚本功能) 或 火狐 + Tampermonkey,它们的下载行为规矩一些。
💡 手机上导几百个角色,本来就是这个工具最吃力的场景(每个角色一个文件=几百次下载)。
v1.19 起断了不用从头来:面板上有个「从第几个角色开始」。 日志里每个角色都带序号(
✅ [37/211] 【某某】…), 被打断之后看最后成功的是第几个,下次填它的下一个接着跑就行。⚠️ 顺序按「最近聊过」排,中途别去聊天,不然编号会变。要省事还是用电脑导全量、手机只负责读。
Q:导出跑到一半,文件却一个都没出现? 八成是「下载前询问每个文件的保存位置」没关,或者「允许下载多个文件」没点允许。 尤其是"前几个下来了、后面就没了"这种,看上面那条 《前几个角色都弹了下载,后面几个就不弹了?》——那条策略拦人的时候不给任何提示。
Q:手机上(或电脑上)换字体没反应?
字体不是跟着网页下载的,它用的是你设备里已经装了的字体。 本仓不附带字体文件(不代第三方字体做分发),所以「京華老宋 / 站酷小薇 / 朝華正文 / 庆科黄油」 这几款只有你自己装过才会生效——手机上一般都没有,切了自然没变化。
现在列表里加了三个带「(手机可用)」的:系统宋 / 系统黑 / 系统楷, 用的是 iOS、安卓自带的中文字体,手机上切得动。 电脑上想用那几款好看的,把字体装进系统,网页里就会自动认出来。
Q:阅读器说「一个 zip 都没有」? 你多半选了云盘目录。先把文件夹复制到本地硬盘再选。
Q:有几个压缩包的文件名是一串字母数字,不是角色名?
那说明这张角色卡已经被作者下架或删掉了,不是脚本出错。
卡片没了之后,连「这个角色叫什么」都取不到,脚本就退回用角色 ID 的前 8 位当文件名—— 但聊天记录照常完整导出,正文一条不少。这一条在真实账号上核实过:文件名变成字符串的 那几个,去 mufy 上查确实都已经下架了。
想认出是谁:打开包里的 00_目录.md,或者随便点开一篇 md 看看正文,一眼就知道了。
(改文件名的话,把开头那串换成你认得的名字就行,不影响内容。)
Q:文件名写的是 A 角色,点进去却是 B 角色的聊天记录?
这是一个真 bug,v1.20 已修。 抱歉。
原因:文件名要先「洗」一遍才能给操作系统用——/ : * ? " < > | 这些字符会被换成 _,
连续空格压成一个,太长的还会截断。于是两个不同的角色名,可能被洗成同一个文件名
(比如「夜色/温柔」和「夜色:温柔」都变成 夜色_温柔)。
旧版判断"要不要在文件名里补角色 ID 来区分"时,比的是原始角色名,
就认为这两个不重复 → 两个压缩包同名 → 浏览器把后下载的那个存成 xxx (1).zip。
谁拿到"正名"取决于下载先后,于是名字和内容就对不上了。
v1.20 改成按洗过之后的文件名判重,并且在导出过程中再挡一道, 绝不允许两个角色写出同一个文件名。
🔴 v1.20 只修了一半,v1.39 才补齐。 v1.20 挡的是同一次导出之内的撞名;
可那张防撞表一关面板就清空了,于是两个"洗完同名"的角色分两次单独导时,
第二个照样被浏览器存成 xxx (1)——名实又对不上。
导电子书时最容易中:EPUB 的文件名为了书架上好看,连时间戳都不带(ZIP 带)。
v1.39 起会把"这个文件名归哪个角色"记下来,跨次也认得出来,
撞上就自动补角色 ID,并在日志里写明原因。
已经导出来的怎么办? 不用重导也能认出来:
每个压缩包里的 00_目录.md 开头写着真正的角色名,
_原始数据.json 里还有 characterId。对着改一下文件名就行。
(想省事就更新到 v1.39 重导那几个——尤其是文件名带 (1) (2) 的那些。)
Q:在 mufy 里往上翻聊天记录,一直弹 Request failed with status code 429?
429 是 mufy 的服务器在说「你请求太频繁了」,不是脚本坏了,也不是你手机的问题。 它是临时的,不会弄坏你的记录,也不是封号。
三个常见诱因,按顺序试:
- 刚跑完大批量导出 —— 短时间内特别容易撞上。停手等 30–60 分钟, 这段时间别反复去点,越点越容易把限流续上。
- 开着加速器 / VPN / 代理 —— 出口 IP 是共享的,很容易被当成异常流量。 关掉,或者换个网络(WiFi ↔ 流量)再试。
- 连续快速往上翻 —— 每翻一次就是一次请求,慢一点。
想分清是账号被限还是网络被限:拿另一台设备 / 另一条网络打开 mufy 翻同一个角色。 一边正常一边不行 → 是那条网络的问题;两边都不行 → 账号层面的临时限流,等着就好。
💡 导出的意义就在这儿:记录已经在你自己硬盘上了,用网页阅读器或电子书随时能读, 不用再指望 mufy 那边翻不翻得动,也不会再触发任何限流。
Q:报错 HTTP 403 是什么意思?
403 不是「没登录」(那是 401),是服务器认得你,但这次不让过。两类常见原因:
- 站点前面的防护把请求当成了机器人。 开着加速器 / VPN / 代理、网络环境异常、 或者短时间请求太密,都可能触发。关掉加速器、换个网络、等几分钟再试,多半就好了。
- 这个角色或资源,你的账号确实没有权限看。 那就只能跳过它。
v1.19 起错误信息里会直接写出这两条,不再只甩一个数字。 日志里那一行还会带上是哪个接口、哪个角色,方便定位。
Q:提示「续不上登录态」? mufy 的登录凭证只活 15 分钟。脚本会自动续,真提示这句就是掉登录了, 刷新 mufy 页面(必要时重新登录)再来。
Q:跑到一半有个角色报错了? 不影响其他角色。v1.13 起单个角色失败会跳过继续跑,日志里当场标出来, 结尾再汇总一次「成功几个、失败几个」并列出失败的角色名和 ID —— 拿那个 ID 用「手动填角色 ID」补一遍就行。
唯一的例外是掉登录:那不是「这一个角色的问题」,继续跑只会刷出几百条一样的错, 所以会整批停下来,让你刷新 mufy 页面(必要时重新登录)再来。
Q:结尾说「有 N 段没导完整」,怎么知道是哪几段?
v1.24 起会直接列出来,不用一个个点开找:
🔴 有 2 段没导完整,分别是:
· 【某角色】2026-05-20 那段 接口说共 1458 条,只取到 1000 条(换小页重试过,还是这么多)
· 【另一个】2026-06-02 那段 …
对应文件的开头也仍然有同样的红字。
Q:某个存档导出来只有 1KB,点开只有几句话?
这一段的完整内容脚本没拿到,但通常救得回来。
发生了什么:mufy 的存档记录本身只保存一问一答,正文要另外按 session 去取。 有些很久以前的存档,那个取正文的接口会一条都不返回;脚本这时只能退回去写存档 自带的那一对——所以文件会比当年真聊的那些短得多(常见的只剩 1KB 上下,具体多小 取决于那一问一答本身有多长)。
救法(用户实测有效):
- 去 mufy 里找到那个存档,把它「载入」,让它变成你当前正在聊的那一段
- 回来重新导出这个角色
载入之后接口就给得出全文了,导出来的就是完整记录。
v1.28 起这件事不再是静悄悄的:这样的段在文件开头、00_目录.md 里
(红点标记)、以及导出结束时的日志里都会写明白,还会告诉你上面这个救法。
以前它跟一段真的只聊了两句的对话长得一模一样,根本分不出来。
Q:同一份聊天记录,怎么导出来了两份?
因为你在 mufy 里载入过某个存档。载入之后它同时又成了这个角色的 「最后一次聊天」,于是存档那条路和「最后一次聊天」那条路各给出一个 session,内容却是同一份——两段的条数和文件大小会分毫不差。
v1.28 起会自动合并:只有一字不差的两段才合并(载入之后你又接着聊过的,
条数就不一样了,那是两段真不同的记录,不会碰)。合并时留下有存档的那一份
(标题用你写的备注更好认),日志和 00_目录.md 里都会写一句「已合并 N 段重复的」,
所以段数少了不是丢了东西。
Q:接口说共 1156 条,实际只取到 974 条——是 mufy 把记录弄丢了吗?
是。已经有两位用户各自查清了这件事:在 mufy 里把那段往上翻到顶, 那边确实就只剩这些——mufy 迁移过服务器,并且发过公告说会丢一部分聊天记录。 它返回的总数还是丢失之前的数字,所以才会出现「接口说 1156、实际只有 974」。
也就是说,看到这个提示时,少掉的那些在 mufy 上通常也已经翻不出来了, 不是脚本没抓到。v1.26 起提示里会把这一点写清楚,v1.28 又补了一句: 这种情况重导多少次都是这么多,不用白等。
想确认是哪一种,自己判一下:
去 mufy 里打开那一段,往上翻到底。
- mufy 自己也只显示得出 900 多条 → 那边就只有这些,脚本没法凭空变出来 (可能是对方的服务端只让翻这么深,也可能真的少了)
- mufy 能翻出 1156 条、我们只导到 974 → 那是我们的问题,请把角色名和这段的日期告诉我们
v1.24 已经先尽了一份力:发现拿到的比接口说的少时,会自动换一种翻页方式重试一遍, 两次结果按 ID 合并去重。测下来这能救回一类情况(服务端对大页翻页有深度限制时, 小页能接着往下翻);如果换了还是一样多,日志里会写明「换小页重试过,还是这么多」—— 那就不是我们没尽力,是那边给不出来了。
Q:「全部合并成一份 Markdown」是什么意思?是把所有东西都装进去吗?
不是。它决定的是"产物长什么样",不是"导多少"。 导多少由上面那一栏(当前角色 / 全部聊过的角色 / …)说了算,这一栏只管形状:
| 选哪个 | 出来是什么 |
|---|---|
| 每段对话一个文件(ZIP) | 一段存档一个 .md,打包成一个压缩包,里面还有 00_目录.md 索引 |
| 全部合并成一份 Markdown | 这一个角色的所有段落接成一整个 .md,从头翻到尾 |
所以选「全部聊过的角色」+「合并」= 每个角色各出一份 md, 不是所有角色挤进一个文件(点导出时的确认框也会写「每个角色一份 Markdown」)。
合并那一份里有什么:角色名、统计(存档数 / 对话数 / 消息数 / 导出时间)、
开场白单独一节,然后一段一节按顺序排下来;该有的提醒
(「这段只有存档摘要」「这段和另一段重复、已合并」)也都在。
比 ZIP 少的只有 00_目录.md —— 合并版靠标题分节,用不着索引。
.json 文件
(不像 ZIP 那样打包在一起),别以为漏了。
怎么选:想一口气通读用合并;想当备份、方便查某一段用 ZIP。JSON 两种都建议勾着。
Q:分批导出来好几个包 / 好几本书,怎么合成一本?
看你手上是哪种。
- 手上是
zip:把这个角色的所有分批 zip 放进同一个文件夹,跑一次python make-epub.py就直接出一本完整的书。它认的不是文件名,是包里记着的「我是第几批、一共该有几段」, 顺序不会乱,少放了一批还会当场喊你少几段,不会闷声给你一本残书。 - 手上只有
.epub:也能合,但我们的脚本不做这件事(成品书里没有原始数据), 要么重导一次 ZIP 走上面那条,要么用别的电子书工具合。⚠️ 在线合并网站等于把整本聊天记录传给陌生服务器,自己掂量。
两条的完整说明都在「第二步之 B:转成电子书」那一节里 (zip 那条在「用 Python 脚本转已有的 zip」这个折叠块里,点开就是)。
Q:最多能导多少个角色?有上限吗?
有,12000 个——但那是脚本自己的防失控上限,不是 mufy 的限制。
脚本翻角色列表时,一次要 200 个(200 是 mufy 那边的上限,填更大它直接报
PageSize must be at most 200),最多翻 60 页 ⇒ 12000 个角色。
这个数只是为了「万一分页出岔子,别让它无限空转」,正常账号远远够不到。
🔴 v1.45 起,真撞到这个上限会明确喊出来(并告诉你这是脚本的上限、可以调高)。 v1.44 及以前是静默的:翻到头就停,一个字都不说,而且当时一次只要 50 个, 上限其实只有 3000。真有那么多角色的话,多出来的会被悄悄漏掉。 有用户问到这个数,才发现它一直不吭声。
💡 v1.45 同时把每次要的数量从 50 提到 200,请求数降到四分之一 (292 个关注:6 页 → 2 页,快了不少)。换页大小会不会漏人是验过的: 两种页大小拿到的角色数相同,也和接口自报的总数一致。
Q:勾了「清理 think / 状态栏 HTML」,会把状态栏里的内容删掉吗?
不会——状态栏里的字一个不少,被拆掉的是包着它的标签。
<div> <span> <table> <td> 这类标签会被去掉,标签之间的文字全部保留:
好感度、时间、地点、数值都还在。
<br> 这种换行标签也在拆除名单里,所以原本分好几行的状态栏
可能会挤成一坨。内容没少,就是不好看了。
真正会被整段删掉的只有三种:
| 会整段消失 | 说明 |
|---|---|
<think>...</think> |
连里面的内容一起——这本来就是这个选项的主要目的 |
| HTML 注释 | 给模型看的备注,读起来是纯噪音 |
<style> / <script> 块 |
所以状态栏靠 CSS 上的色、画的框会没,字还在 |
<think> 里面的话,会跟着一起没。
(另外 <details> / <summary> 不在拆除名单里,用它搭的状态栏会原样保留,见上面那条。)
最要紧的一句:不管你勾不勾,_原始数据.json 里永远是完整原文,一个字都不动。
内容不会丢,最坏也就是回 JSON 里翻。
怎么选:想读着干净(当小说翻)就勾上;想保住状态栏的原样排版就别勾—— md 里会留着原始 HTML,用支持 HTML 的阅读器打开还是原来的样子。 EPUB 那条路一律清理,不管你勾不勾:电子书格式不允许留 HTML 碎片。要原样就看 md 或 JSON。
Q:导出的长对话好像少了内容?(书从中间开始 / 前面完整后面缺失)
第一步:看导出结束时那段日志的最后几行,不用打开任何文件。
脚本每次收尾都会把有问题的段单独用红字喊出来。所以:
- 没有 🔴 红字 → 接口说有多少条,脚本就拿到了多少条,一条没漏。
绝大多数情况下这就等于"完整",那"少的那些"是 mufy 那边已经没有了。
⚠️ 但有一个例外,见下面那条——所以如果你那段特别长,别只看这一条就下结论。 - 有 🔴 红字 → 照下面这张表对号入座,三种情况救法完全不同:
| 红字写的是 | 什么意思 | 怎么办 |
|---|---|---|
| 「第 N 页取失败」 | 抓取途中网络抖了 | 把那个角色单独重导一次,通常就好 |
| 「接口说共 N 条,只取到 M 条」 | 多半是 mufy 那边丢了(见上一条) | 重导也是这么多;去 mufy 里翻到底自己确认一下 |
| 「只有存档摘要」(文件才 1KB) | 接口一条正文都没给 | 在 mufy 里把那个存档「载入」再重导(见上面那条) |
第二步:去 mufy 里自己确认一眼。 打开那个角色,一直往上翻到最顶——
- 翻得到最早那几句 → 那是接口没给全,请把角色名告诉我们;
- 翻不到、mufy 里也是从那儿开始的 → 那边确实只剩这些了,脚本变不出来。
🔴 例外:一整段上千条的对话,接口自报的总数本身就可能是被截过的 —— 而且这一种我们救不回来。
一位用户拿 mufy 官方导出对过账(那一次官方那边还留着早期内容,另一位用户 三天后再导时官方那份也只剩中段了,见下面 📌):同一段对话官方那边 2971 条, 而接口说的和我们拿到的都是 1000 —— 两个数一样,所以旧版以为拿全了、一声不吭。
v1.35 起判据换了:不再看接口自报的总数,只看「这一页装满了没有」—— 满页就继续要下一页,出现不满的一页才算到头。所以上面这种「总数撒谎」 已经不会再让脚本提前收手了(v1.33 / v1.34 那两轮补丁也被它吸收掉了)。
🔎 同版加了长段体检:一段超过 500 条时,导出日志和
00_目录.md里会写明 「接口说 N 条 / 实际取到 M 条 / 最早一条是哪天」。 看最早那个日期,你自己就能判断有没有缺前面 —— 不用再导一遍去试。💡 怎么读这几行:如果那一段是「接口说多少=实际取到多少」, 而最早那条的日期比你印象里的晚,那就是接口在那之前不给了, 不是脚本没抓到 —— 别再重导了,重导多少次都是这些。
🔑 重点不是"哪一年",是"这一段有多长"。 常有人问「为什么有人能完整导出 2025 年的记录,我却不行」—— 差别不在记录多老,在你的历史是怎么切成段的:
结果 段短、段多(几十上百条一段,平时按过「保存并开启新对话」) ✅ 不管多老都导得全,因为往回翻的深度从来没深过 一整段就上千条(一路聊下来没存过档) ⚠️ 早的那部分够不着,书就会「开场白之后直接跳到中间」(实测过一个 25000 条的账号,992 段、平均一段 25 条,一条不缺; 而撞上这个的两位用户,都是一两段、每段上千条。)
📌 2026-08-14 又一位用户把归属彻底实锤了(值得抄他的验法): 他的当前对话只有 1000 条、缺开头,于是他在 mufy 里手动翻到最顶(UI 能显示全部)、 就地新存了一个档、再用 mufy 官方导出——结果和脚本导的一模一样,还是 1000 条。 ⇒ UI 显示得出来 ≠ 接口给得出来;翻到顶再导没有用,官方导出也一样。 判断是谁的问题,拿官方导出对照一次就够了。
🔑 而他其实什么都没丢:他早期存过的档各自完整(从第一条到存档点), 和最新窗口拼起来正好覆盖全程。被截掉的开头就躺在早期存档的那几个文件里—— 别只盯着最后一段看,先把几段的范围对一对。
📌 所以预防办法只有一个,而且真的有用: 在 mufy 里适时按「保存并开启新对话」,别让一段长到上千条。 段一多一小,就永远碰不到这个坎。 已经撞上的,更早的内容只能走 mufy 官方的引继码导出(那是另一条路)。
⚠️ 但接口真的不给的那部分,谁也变不出来: 在那位用户的那一段上,我们试过的三种要法都停在 1000 (pageSize=500 × 2 页/从第 3 页往后要/一次请求要 2000 条); 她在 mufy 网页里往上滑也翻不回去。这一段更早的内容,这个脚本拿不到。 (探测留着:真捞到了会在日志里写「📈 往后又翻出 N 条」,没这行就是没捞到。)📌 这一例后来的进展,一并交代:她重导拿到 2026 条(两段:1026 + 1000), 离官方那份的 2971 仍差约 945 条。 而 1026 那段,v1.34 及以前根本不会去探它 —— 老判据要求「正好拿满 且是 500 的整数倍」, 1026 不是,于是它抓到 1026 就收手了,第 4 页从来没被问过。 v1.35 换掉判据之后这个洞就没了(不再依赖任何"整数倍")。 所以:一整段上千条的对话,用 v1.35 再导一次是值得的; 导完看那行 🔎 长段体检里的「最早一条」,就知道有没有够到你记忆里的开头。 那更早的内容怎么办?先试 mufy 官方自己的导出(它出的是一个
.txt)—— 但别把它当救命稻草,两位用户的结果是相反的:
官方导出的结果 用户 A(8/7 导的) ✅ 拿到了 2971 条,从最开头就有 用户 B(8/10 导的) ❌ 和这个脚本导的一样,也只有中段,起点、时间都一模一样 所以真正的结论不是"换条路导就能拿回来":两条路都拿不到的时候, 那部分在 mufy 那边就是没有了。已经导下来的每一份都留着, 不同工具、不同时间导的产物合起来,通常比任何单独一份都全。
🕐
⚠️ 别拿书里那个「⏰ 时间」判断缺没缺 —— 那是剧情里的时间 (角色扮演状态栏写的,可能是2024/7/27这种),和真实时间没有关系。 要判断有没有缺前面,看体检行里的「最早一条」,那个才是真实日期。 (真有人拿剧情时间对过账,结论全错——包括我们自己。)💡 同时做这件事减少以后再丢:在 mufy 里按「保存并开启新对话」, 让一段别长到上千条。段一多一小,每段都离那个坎远远的。
⚠️ 只有"一整段就上千条"才会碰到这个。两万条分散在几百段里的那种完全不受影响。
📌 想自己较真的话(可选,不看也不影响):勾了「附带 JSON 完整备份」的话,
_原始数据.json里每段都有expectedCount(接口说共多少条)和messageCount(实际拿到多少),两个数一样就是完整的。 结尾日志判断的就是这两个数,所以日志没红字=这两个数处处相等,不用自己翻。
v1.8 之前有个坑:长对话翻页翻到一半失败时,已经抓到的几百条会被整个丢掉, 退回成存档里的一问一答(2 条),而且只在角落留一个小小的
⚠️ 。 现在改成抓到多少留多少、并在文件开头和结尾都明确报出来。 长对话才需要翻页,所以这个坑专挑长记录下手 —— 如果你之前用旧版导过,值得重导一次。
只有手机、没有电脑也能用。v1.10 起电子书直接在浏览器里生成,不再需要 Python, 所以整条链路手机上就能闭环:装脚本 → 导出 → 出 EPUB → 读。
✅ iPhone(Safari + Userscripts)已实测走通全程。 ✅ 安卓也走通了:有安卓用户照着下面这份教程从头走了一遍,没有遇到别的问题。 (我们自己没有安卓设备,这一节的验证来自真机用户,不是我们测的。)
1. 装 Userscripts(App Store 搜,免费开源)。iOS 上没有 Tampermonkey,那个只有 Mac 版。
打开它一次,它会让你指定一个存脚本的文件夹——在「文件」App 里新建一个就行。
2. 打开扩展:设置 → Safari → 扩展 → Userscripts 打开,网站权限给「允许」 (选「始终允许」省事,不然每次都要点一下)。
🚨 别在「无痕浏览」里用。 已有用户卡在这儿:脚本装好了、Userscripts 面板里 也看得见而且是启用状态,就是不出按钮——原因是他开着无痕。 换成普通标签页(必要时把 Safari 完全关掉重开)就好了。
iPhone 上怎么确认脚本本身是好的:在 mufy 页面点地址栏的 ᴀA → Userscripts, 弹出的面板里——
- 右上角那个总开关要是开着的(控制要不要往页面里注入脚本)
- 列表里能看到「Mufy 批量导出聊天记录」,而且是亮白色的 (灰色 = 这条被停用了)
这两样都对、却还是没按钮的话,问题就不在脚本上,看上面那条「无痕」和网站权限。
3. 把脚本放进去:Safari 打开下面这个地址,全选复制——
https://raw.githubusercontent.com/willwefind/mufy-batch-export/main/mufy-batch-export.user.js
然后点地址栏左边的 ᴀA / 拼图图标 → Userscripts → 新建脚本,粘贴进去保存。
💡 更省事的一种:直接在 Safari 里打开上面那个网址,页面上多半会自己冒出一条 「Userscript Installed / Tap to install」的横幅,点它就装好了,不用复制粘贴。 以后更新也走这条:再打开一次这个网址 → 横幅变成 「Tap to re-install」→ 点一下就覆盖成新版。 (🚨 点之前先下拉刷新一下页面 —— 那个网址有几分钟缓存,不刷新可能装到的还是旧版。 装完记得回 mufy 页面刷新一次,理由见下面那条。 想确认版本:打开导出面板,标题右边写着
v1.45就是新的。)
🚨 保存完,回到 mufy 那个标签页刷新一次。 脚本只在页面加载的那一刻注入, 你装脚本时开着的那个标签页是"装之前"的,不刷新就永远不出按钮 ——面板这时候显示的是
No matched userscripts,看着像没装上,其实只差一次刷新。 已有 iPhone 用户卡在这一步。
4. 导出:Safari 打开 mufy 登录 → 随便进一个角色的聊天页 → 左下角出现 「⬇ 批量导出」 → 范围选「当前角色」、输出方式选「每个角色一本电子书(EPUB)」→ 开始。
5. 读:Safari 右上角的下载箭头(或「文件」App → 下载)里就是那本 .epub,
点开 →「用其他应用打开」→ 微信读书 / 图书 / 静读天下。
安卓上的 Chrome 装不了扩展,所以不能照电脑那套走。有两条路,任选其一。
这类国产轻量浏览器自带脚本功能,装个浏览器就够了,不需要 Tampermonkey。
⚠️ 先说一个特别容易走错的地方: 这些浏览器里有个「精选用户脚本」页面(写着"这里汇总了一批常用的油猴脚本")。 那是浏览器自带的脚本市场,我们这个不在里面——在那儿翻遍了也找不到。 要走的是下面「装外部脚本」这条路。
1. 装浏览器:应用商店搜 X浏览器 或 Via 浏览器(都是几 MB 的小软件)。
2. 装脚本 —— 先试最省事的:
用它打开下面这个地址:
https://raw.githubusercontent.com/willwefind/mufy-batch-export/main/mufy-batch-export.user.js
浏览器认得 .user.js 这种文件,通常会直接弹出「是否安装此脚本」,点安装就完事了。
3. 没弹出来的话,手动加:
- 打开浏览器菜单(右上角三个点,或底部的 ☰)
- 找脚本相关的入口——不同版本叫法不一样,可能是「脚本管理」「用户脚本」 「油猴脚本」,位置可能在「工具箱」或「设置」里
- 进去之后点「新建」或「添加」→ 把上面那个网址填进去; 如果只能粘代码,就回到那个网址全选复制,整段粘进去保存
4. 回 mufy:浏览器打开 mufy 登录 → 进任意角色的聊天页 → 刷新一次 → 左下角出现「⬇ 批量导出」。
想用和电脑上一样的 Tampermonkey 就走这条。火狐安卓版支持扩展(只能装它推荐列表里的, Tampermonkey 在列表里)。
- 应用商店装 Firefox
- 菜单(右下角三个点)→ 扩展 / 附加组件 → 搜 Tampermonkey → 添加
- 然后点第 2 步那个脚本地址,Tampermonkey 会弹安装页,点安装
- 打开 mufy 登录 → 进聊天页 → 刷新 → 左下角出现按钮
🚫 别用 Kiwi 浏览器了。它以前是安卓上装 Chrome 扩展最常见的选择, 但作者已经停止开发,不建议再依赖它。
- 导出:点「⬇ 批量导出」→ 范围选「当前角色」(先只导一个试)→ 输出方式选「每个角色一本电子书(EPUB)」→ 开始导出。
- 文件在哪:一般在
内部存储/Download,用系统自带的「文件」App 找。 浏览器自己的「下载」列表里也能直接点开。 - 读:点那本
.epub→「用其他应用打开」→ 静读天下 / 微信读书 / 多看 / Moon+ Reader。
- 🔴 第一次批量下载会被拦一下:浏览器可能弹「是否允许下载多个文件」,点允许。 它也可能不问、直接静默拦掉——症状是前一两个下来了、后面就再也不弹了。 这时去点地址栏左边的锁/ⓘ 图标 →「网站设置」→「自动下载」→ 改成「允许」,再导一次。 有的浏览器还会每个文件都问一次保存位置——在浏览器设置里把「下载前询问保存位置」关掉。
- 别切后台、别锁屏(这条比 iPhone 上更要紧,安卓杀后台更狠)。
- 先只导一个角色试,确认整条路通了再说。
- 手机上建议选 EPUB,别选 ZIP:几百个 zip 灌进手机下载目录很难管,而且在手机上也没法用 网页阅读器读起来也挤(手机上用「直接选 zip 文件」多选整包,能用但界面是按大屏排的)。
⚠️ 一次导几百个角色,手机上没实测过(实测的是单个角色)。要整体备份, 能用电脑就用电脑;只有手机的话建议分批导,别一次点全部。⚠️ 跑的时候别切到别的 App、别锁屏。手机浏览器会把后台页面暂停甚至直接回收, 导出会断。v1.18 起脚本会请求「保持屏幕常亮」,但那只挡得住屏幕自动熄灭, 挡不住你手动锁屏或切走——把手机放着让它跑完最稳。
更多设置与技术细节(点开)
这张表其实是三组,每组各选一个,互不替代: ① 导哪些(当前角色 / 全部聊过 / 关注 / 手动填 / 面具 / 角色卡)→ ② 产物长什么样(ZIP / 合并成一份 md / EPUB / 酒馆 jsonl)→ ③ 两个开关。 ②不影响导多少,只决定东西打包成什么形状 —— 这一点最容易看混, 详见「全部合并成一份 Markdown 是什么意思」那条 FAQ。
| 选项 | 说明 |
|---|---|
| 当前角色(本页·全部存档) | 只导你正在看的这个角色,它的全部存档都导 |
| 当前角色 · 只要正在聊的这一段 | 只导你此刻正开着的那一段对话,不碰其它存档(v1.39) |
| 全部聊过的角色 | 想整体备份就选这个 |
| 全部已关注角色 | 你点过关注的全部角色,包含从没聊过的(会自动跳过并报数) |
| 手动填角色 ID | 从地址栏 roleId= 后面那串复制过来 |
| 连没聊过的也导(只有开场白) | 只在「全部已关注角色」下出现。关注了但从没聊过的角色没有对话记录,但开场白还在卡上(常有一两千字)——勾上会给它们各出一个只装开场白的包。默认不勾(v1.44) |
| 救回卡已消失的角色 | 🆘 作者把卡设为私密之后,那个角色会从列表里整个消失、mufy 网页上也打不开——但记录还在。把浏览器历史里那条聊天页地址整条粘进来就能救回来,见这一节(v1.41) |
| 每包最多多少段对话 | 留空=一个角色一个包。对话上百段的角色填 20,改成一批批地抓、抓完就放,内存峰值只跟一批有关(v1.23) |
| 从第几个角色开始 | 只在成批导时出现。中断后接着跑用:看日志里最后成功的是第几个,下次填它的下一个(v1.19) |
| 人设面具(全部) | 导的是面具库,不是聊天记录。见这一节 |
| 我创建的角色卡(全部) | 导的是你自己写的卡,含图片。见这一节(v1.12) |
| 每段对话一个文件(ZIP) | 默认。N 段对话 = N 个 md,打包成一个 zip |
| 全部合并成一份 Markdown | 想一口气通读时用。一个角色一份(不是所有角色挤进一个文件),开场白和每段对话在同一个 md 里依次排开 |
| 每个角色一本电子书(EPUB) | 直接出成品书,不用装 Python。一段对话一章,开场白单独一章,自带封面 |
| 酒馆对话(.jsonl) | 导进 SillyTavern 用。一段存档一个文件,含导入说明(v1.21) |
| 清理 think / 状态栏 HTML | 只影响 Markdown 可读性;JSON 永远是完整原文。EPUB 一律清理(书是拿来读的)。 |
| 附带 JSON 完整备份 | 建议勾着,这才是真正的备份 |
isFollowed=true 返回的是你关注的全部角色,包括从没聊过的,而不是两者的交集;
反过来也有你聊过却没点关注的。想整体备份,选「全部聊过的角色」。
实测某账号:关注 291 个,其中真的聊过 192 个,从没聊过 99 个,另有 20 个聊过但没关注。
用到这几个接口,都带 Authorization: Bearer <localStorage['mufy-token']>:
| 接口 | 作用 |
|---|---|
GET /api/characters/query_session |
角色列表(含 lastSessionId) |
GET /api/sessions/query_archives?characterId= |
某角色的存档列表 |
GET /api/dialogs/query?sessionId=&characterId= |
某段对话的全部消息 |
GET /api/characters/get?id= |
角色名和 开场白(greeting) |
POST /api/masks/query |
人设面具库(v1.11 用)。是 POST,字段叫 page(不是 pageNum),pageSize 上限 100 |
GET /api/characters/list?creatorId= |
你自己创建的角色卡清单(v1.12 用) |
POST /api/characters/metadata |
作者视角的完整卡片(body {id})。characters/get 是读者视角,人设/情节设定/输出设定/正则一概没有 |
流程:取角色列表 → 每个角色取存档 → 按 sourceSessionId 去重、再补上 lastSessionId
→ 逐段抓全文 → 加上开场白 → 渲染 Markdown → 打包 ZIP → 浏览器下载。
ZIP 是脚本按格式自己拼的,压缩用浏览器原生的 CompressionStream,不引任何外部库。
EPUB 说到底就是一个结构固定的 ZIP,所以 v1.10 把整套生成逻辑搬进了浏览器——
封面用 canvas 画(不带任何字体文件,用系统自带的宋体),从此不需要 Python。
make-epub.py 仍然保留,给「已经导过一堆 zip、不想重导」的人用。
两条路出的书是等价的,这不是估计:在一个 200 多角色的真实账号上, 两边各出了 211 本,逐项比对书 ID、章节清单、目录标题、以及每一章的正文全文, 211 本全部逐字节一致。合规性用官方 epubcheck 5.1.0 校验:0 errors / 0 warnings。
移植时逮到过一个真差异:JS 的
slice按 UTF-16 码元算,Python 的[:n]按字符算, 标题里只要出现 emoji 或花体字(一个字占两个码元),两边就会截出不同长度。 211 个里咬中 3 个。改成按码点截之后归零。
请求之间留了 120–300ms 间隔,遇到限流会退避重试——别改激进,那是别人的服务器。
有人担心长对话会被吞。这里是合成一段 1 万轮(2 万条消息)的对话推过整条链路的实测结果:
| 环节 | 结果 |
|---|---|
| 翻页抓取 | 40 次请求,2 万条全到,0 重复 0 遗漏 |
| 渲染 Markdown | 98 ms,单篇 24.5 MB |
| 打包 ZIP | 448 ms,堆内存 33 → 50 MB |
| 转 EPUB | 成书,单章 XHTML 21 MB |
| EPUB 在微信读书 | 真机导入,打开正常、跳目录正常 |
| 网页阅读器 | 2 万条一次性进 DOM(约六万个元素),不卡 |
结论:不需要按章切分,也不需要分页渲染。 一万轮以内不用做任何特殊处理。
另外实测:/api/dialogs/query 的 pageSize 不限于 100(试到 2000 都接受),
而且 100 / 200 / 500 三种页大小翻出来的唯一 dialogsId 集合完全一致、0 重复 0 漏掉——
偏移量是准的。所以 v1.9 起默认每页 500,一万轮对话的请求数从 200 降到 40,
暴露在网络抖动下的机会少 5 倍。
真实性说明:合成文本是同一句重复,所以压缩率高得不真实(21 MB 的章压成 96 KB)。 但压力点是解压后那 21 MB 的解析与渲染,那部分是真的。
脚本读你浏览器里的 mufy 登录凭证,这是它能工作的前提。 它只把这个凭证发给 mufy 自己的接口,不外传、不上报、不统计、不引第三方库。
但你不该因为我这么说就信。源码在这儿摊着,三万字节,能读的自己读一遍, 读不动的可以整段丢给任何一个 AI 让它讲给你听。 「作者说它安全」从来不是安全的理由,「你能自己查」才是。
往浏览器控制台粘代码本身有风险,浏览器弹的那句「不要粘贴不明代码」是对的。 装 Tampermonkey 至少代码留在本地、随时可查。
GNU Affero General Public License v3.0(AGPL-3.0)。详见 LICENSE。