#!/usr/bin/env python3 """读取 hpbr_bosszhipin_client.db,把 Contact 表(联系人摘要) + MessageTable 里的 resume(招聘模式收到的候选人简历,ChatResumeBean) / job(牛人模式收到的职位卡片, ChatJobBean) 都反序列化导出成 JSON。两者都是明文 Java Object Serialization, 不需要解密。myRole=1 表示这条联系人是"你当老板、对方是候选人",myRole=0 表示 "你当牛人、对方是招聘方"——同一套 Contact 表字段两种角色复用,见 README 第五节。 用法: python3 parse_resumes.py [data/hpbr_bosszhipin_client.db] > resumes.json """ import json import sqlite3 import sys from pathlib import Path import javaobj DB_PATH = Path(sys.argv[1]) if len(sys.argv) > 1 else Path(__file__).parent / "data/hpbr_bosszhipin_client.db" def to_plain(value): """把 javaobj 解出来的对象树递归拍平成 JSON 能序列化的 dict/list/基础类型。""" if isinstance(value, (str, int, float, bool)) or value is None: return value if isinstance(value, (list, tuple)): return [to_plain(v) for v in value] if isinstance(value, dict): return {k: to_plain(v) for k, v in value.items()} if hasattr(value, "__dict__"): return { k: to_plain(v) for k, v in vars(value).items() if k not in ("classdesc", "annotations") } return str(value) def parse_blob(blob: bytes): obj = javaobj.loads(blob) return to_plain(obj) def collect(con, column, out_key): """从 MessageTable 里挑出某个 BLOB 列(resume 或 job)非空的行,反序列化。""" rows = [] for row in con.execute( f"SELECT mid, fromUid, toUid, time, {column} FROM MessageTable WHERE {column} IS NOT NULL" ): try: parsed = parse_blob(row[column]) except Exception as e: parsed = {"_parse_error": str(e)} rows.append( { "mid": row["mid"], "fromUid": row["fromUid"], "toUid": row["toUid"], "time": row["time"], out_key: parsed, } ) return rows def main(): con = sqlite3.connect(str(DB_PATH)) con.row_factory = sqlite3.Row contacts = { row["friendId"]: dict(row) for row in con.execute( "SELECT friendId, friendName, myRole, expectPositionName, expectSalary, degree, " "workYear, workplace, gender, age, currentInterviewDesc, exchangeResumeUrl, " "videoResumeUrl, bossCompanyName, bossJobPosition, positionName, salaryDesc, jobId, " "note, lastChatText, lastChatTime FROM Contact" ) } resumes = collect(con, "resume", "resume") # myRole=1: 你当老板收到的候选人简历 jobs = collect(con, "job", "job") # myRole=0: 你当牛人收到的职位卡片 result = {"contacts": list(contacts.values()), "resumes": resumes, "jobs": jobs} json.dump(result, sys.stdout, ensure_ascii=False, indent=2) if __name__ == "__main__": main()