6.6 KiB
6.6 KiB
2026-08-19 工作日志
企业微信聊天记录导出(完成)
成果:成功导出 2 个已登录账号的全部聊天记录,共 2792 条消息、88 个会话。
输出文件(wxwork_export/ 目录):
企业微信聊天记录.csv/.xlsx— 全部消息(账号、会话、时间、发送者、消息类型、内容等 12 列)会话汇总.csv/.xlsx— 88 个会话的消息数与时间范围聊天记录_1688856770803435.csv(2756 条)、聊天记录_1688855555743233.csv(36 条)decrypted/— 解密后的 SQLite 数据库
技术要点:
- 企业微信 5.x 用 wxSQLite3 AES-128-CBC 加密(每页 4096B 独立加密,密钥派生
MD5(raw_key + page_no(LE) + "sAlT")) - 16 字节原始密钥从
WXWork.exe进程内存提取(内存中sAlT结构:[key(16B)] + [page_no(4B LE)] + "sAlT") - 已提取 2 个密钥存于
wxwork_keys.json:账号 1688856770803435(db7288a3...)、1688855555743233(d18e7f9a...) - 表名:
message_table(非 message)、conversation_table(非 session)、user_table(非 userinfo) - 消息内容为 protobuf 编码,需递归解析 length-delimited 字段
本轮修复的问题:
SyntaxWarning: invalid escape sequence '\-'— 正则字符串中''提前终止字符串,改为中文引号“”‘’- 5 条短文本消息(如"在不")被
extra_content二进制替换 — 兜底条件从len(content)<3改为content.strip()为空 ?前缀残留(protobuf 内部 tag/length 字节 0x3F/0x7A 混入文本)— parse_content 中增加模式 A(T 残留 T去重保留后半)和模式 B(前导 ASCII 残留清理,支持后跟中文标点)
最终质量:二进制残留 0、?前缀 0、空内容 0、控制字符 0。
未完成/限制:
- 8 个历史用户目录未解密(旧账号未登录,密钥不在内存)——需用户登录后重新提取密钥
- 部分
S:群聊无名称显示为"群聊 S:xxxx" - 脚本需用 venv python 运行(
pycryptodome、openpyxl装在~/.workbuddy/binaries/python/envs/default/)
桌面应用打包(完成)
将导出能力打包为 Windows 桌面应用 dist/企业微信导出助手.exe(19MB 单文件,PyInstaller onefile + windowed + 自定义图标)。
GUI 功能(wxwork_gui.py):
- 一键导出全部聊天记录(CSV + Excel,含进度与日志面板)
- "重新提取密钥"按钮:扫描企微进程内存提取所有已登录账号密钥并保存到 exe 旁
wxwork_keys.json - 每日定时自动导出(时间可设,应用运行期间到点自动触发)
- 输出目录可自定义(默认 exe 旁
wxwork_export/)、完成后一键打开文件夹 - 配置持久化到
wxwork_gui_config.json
技术要点:
- managed Python 3.13 无 tkinter → 改用系统 Python 3.11 建 venv:
C:\Users\pc\.workbuddy\binaries\python\envs\gui311(继承 tkinter,装 pycryptodome/openpyxl/pyinstaller/pillow) - PyInstaller 打包命令:
pyinstaller --onefile --windowed --name 企业微信导出助手 --icon app_icon.ico wxwork_gui.py - 路径兼容 onefile:
APP_DIR = sys.executable所在目录(frozen 模式),密钥/配置/输出目录都在 exe 旁 - 验证:exe 启动进程存活 ✅;打包环境完整导出(2792 消息 + xlsx 校验 2793 行)✅
- 交付:dist/ 含 exe + wxwork_keys.json(2 个已提取密钥)+ app_icon.png
按天/范围导出改造(完成)
用户需求:聊天记录可按"天数"导出(如只导今天)。
核心脚本 wxwork_export_final.py v2.1:
export_messages(dbs, out_dir, date_from=None, date_to=None)— 日期范围过滤(含两端)- CLI:
--days N(最近 N 天含今天)、--date YYYY-MM-DD、--all;默认--days 1 - 输出:单天
按天/YYYY-MM-DD_聊天记录.csv,多天按天/YYYY-MM-DD_至_YYYY-MM-DD_聊天记录.csv,全量在根目录(原结构不变) - 解密缓存:
decrypted/下已有解密文件时跳过(二次运行 1 秒,首次 1-2 分钟),decrypt_with_keys(db_base, out_dir, keys_map, use_cache=True) - 实测:
--days 1今天 0 条正常提示;--days 2正确导出 08-19 的 17 条
GUI wxwork_gui.py:
- 设置卡片新增「导出范围」下拉:只导今天/最近3天/7天/30天/全部历史(
DAYS_OPTIONS=[1,3,7,30,0]) - 导出按钮文字动态化(
_export_btn_text()):"立即导出今天的聊天记录" / "最近 N 天" / "全部聊天记录" do_export(keys, out_dir, log, days=N)计算 date_from/date_to 传给 export_messages;Excel 生成跟随实际 CSV 路径(按天模式在 按天/ 目录生成 xlsx);空范围返回 None 并提示"该时间范围内没有新消息"- 定时自动导出也按所选范围执行;days 持久化到 config
- 清理
_auto_loop死代码(or True: pass)
打包:重新 PyInstaller 打包 dist/企业微信导出助手.exe(19MB),启动验证 ✅,三种模式(days=2/1/0)打包环境实测通过
数据库导出 (CRM 绑定版, 完成)
用户需求:导出数据入库建表、只导出聊天记录、能否取 unionid 做 CRM 绑定。
关键发现(unionid):
user_table.unionid字段存在且有数据:主账号 386 联系人中 332 个有 unionid(微信外部联系人,ozynqs...开头);内部成员无 unionid 但account字段是企微 useridmessage_table.sender_id=user_table.id可关联:2794 条消息中 1746 条(62%)能拿到 unionid- 无 unionid 的消息主要是应用消息(489)/朋友圈(227)/图文链接(133) 等非人工对话
新脚本 wxwork_export_db.py(复用 wxwork_export_final.py 的 decrypt/parse 逻辑):
- 只导出聊天记录:消息表带
sender_unionid/sender_userid/sender_mobile关联列(CRM 绑定键) - 产出
crm_import/:crm_wecom.db(SQLite 三表:chat_messages/chat_users/chat_conversations,每次重建)、聊天记录_仅消息.csv(干净消息 CSV)、create_tables_mysql.sql、create_tables_sqlite.sql - CLI:
--all/--days N/--date;chat_users 总是全量(390 联系人,333 带 unionid) - 实测:全量 2794 条 / 带 unionid 1746 条(62%);CRM 查询示例:高兴亮 669 条、李思佳 111 条
解析增强(wxwork_export_final.py parse_content):
- 模式 C:单数字残留前缀剥离(
^[0-9](?=[\u4e00-\u9fff])(?![\u4e00-\u9fff]{0,2}(?:量词表))),保护 "3月13日" 等合法文本 - 子串去重:meaningful 中互为子串的短文本跳过(
len(t)>=3),消除A | 子串A冗余 - 修复效果:拼接冗余 596 → 0 条;
3关于系统...残留清理为干净文本