""" 读取未匹配填充0.json,对每个json对象: 1. 取filename去掉后缀名,jieba分词后与结果.xlsx中"学科网资料名"进行分词包含匹配 2. 从url中提取数字ID,写入url_id字段 3. 在匹配到的行中,用url_id与"暗码"精准匹配:匹配则xkw_code=暗码值,否则xkw_code=0 4. xkw_code与url_id一致则"一致性"=1,否则=0 """ import json import re import os import jieba import openpyxl SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) INPUT_JSON = os.path.join(SCRIPT_DIR, "未匹配填充0.json") EXCEL_PATH = os.path.join(SCRIPT_DIR, "..", "结果.xlsx") STILL_UNMATCHED_JSON = os.path.join(SCRIPT_DIR, "未匹配填充0_仍未匹配.json") # 过滤掉太短或无意义的分词token MIN_TOKEN_LEN = 2 def strip_ext(name: str) -> str: """去掉文件后缀名""" base, _ = os.path.splitext(name) return base def is_meaningful_token(t: str) -> bool: """token中必须包含至少一个汉字或字母数字字符,否则视为纯标点无意义""" return any(c.isalnum() or '\u4e00' <= c <= '\u9fff' for c in t) def tokenize(text: str) -> list[str]: """使用jieba分词,过滤短词和纯标点/符号""" result = [] for t in jieba.cut(text, cut_all=False): t = t.strip() if len(t) >= MIN_TOKEN_LEN and is_meaningful_token(t): result.append(t) return result def extract_url_id(url: str) -> str: """从url中提取数字ID,例如 https://www.zxxk.com/soft/33839713.html -> 33839713""" m = re.search(r'/(\d+)(?:\.\w+)?$', url) if m: return m.group(1) # fallback: 取url中最后一段数字 nums = re.findall(r'\d+', url) return nums[-1] if nums else "" def build_excel_index(excel_path: str): """ 读取Excel,返回: - rows: list of dict,每行包含 学科网资料名(无后缀)、暗码 - anma_index: dict[暗码str -> 学科网资料名str],用于url_id精准查找 """ wb = openpyxl.load_workbook(excel_path, read_only=True, data_only=True) ws = wb.active headers = [cell.value for cell in next(ws.iter_rows(min_row=1, max_row=1))] idx_xkw_name = headers.index("学科网资料名") idx_anma = headers.index("暗码") rows = [] anma_index = {} # 暗码 -> 学科网资料名(无后缀),学科网资料名为空时存 "" for row in ws.iter_rows(min_row=2, values_only=True): xkw_name = row[idx_xkw_name] anma = row[idx_anma] anma_str = str(anma) if anma is not None else "" # anma_index:只要暗码有值就记录,学科网资料名可以为空 if anma_str and anma_str not in anma_index: xkw_name_noext = strip_ext(str(xkw_name)) if xkw_name else "" anma_index[anma_str] = xkw_name_noext # rows(用于分词匹配):学科网资料名为空则跳过 if not xkw_name: continue xkw_name_noext = strip_ext(str(xkw_name)) rows.append({ "xkw_name": xkw_name_noext, "anma": anma_str, }) wb.close() return rows, anma_index def tokens_match(tokens: list[str], target: str) -> bool: """判断target是否包含所有token""" return all(t in target for t in tokens) def process(input_json: str, excel_path: str, still_unmatched_json: str): print("加载Excel...") excel_rows, anma_index = build_excel_index(excel_path) print(f"Excel共 {len(excel_rows)} 行数据") print("加载JSON...") with open(input_json, "r", encoding="utf-8") as f: data = json.load(f) print(f"JSON共 {len(data)} 条记录") for i, obj in enumerate(data): filename = obj.get("filename", "") url = obj.get("url", "") # 1. 去掉后缀名并分词 name_noext = strip_ext(filename) tokens = tokenize(name_noext) # 2. 提取url_id url_id = extract_url_id(url) obj["url_id"] = url_id # 3. 分词包含匹配,找出所有匹配行 matched_rows = [r for r in excel_rows if tokens_match(tokens, r["xkw_name"])] # 4. 在匹配行中用url_id与暗码精准匹配 xkw_code = "0" if matched_rows: exact = [r for r in matched_rows if r["anma"] == url_id] if exact: xkw_code = exact[0]["anma"] obj["xkw_code"] = xkw_code obj.pop("一致性", None) # 清除旧字段 # 5. xkw_code不为0但与url_id不一致 obj["xwk_code不为0但xkw_code与url_id不一致"] = 1 if xkw_code != "0" and xkw_code != url_id else 0 # 6. 用url_id去暗码字段精准查找 xkw_name_by_id = anma_index.get(url_id) obj["xlsx中的暗码"] = url_id if xkw_name_by_id is not None else "0" obj["学科网资料名"] = xkw_name_by_id if xkw_name_by_id is not None else "" # 7. xlsx中的暗码有值但学科网资料名为空 xlsx_anma = obj["xlsx中的暗码"] xkw_name_val = obj["学科网资料名"] obj["xlsx中的暗码有值学科网资料名为空"] = 1 if xlsx_anma != "0" and not xkw_name_val else 0 if (i + 1) % 100 == 0: print(f" 已处理 {i+1}/{len(data)}") # 直接写回原文件 print(f"写回原文件 {input_json}") with open(input_json, "w", encoding="utf-8") as f: json.dump(data, f, ensure_ascii=False, indent=2) # xkw_code为0的输出到新文件 still_unmatched = [obj for obj in data if obj["xkw_code"] == "0"] print(f"写出仍未匹配记录到 {still_unmatched_json}") with open(still_unmatched_json, "w", encoding="utf-8") as f: json.dump(still_unmatched, f, ensure_ascii=False, indent=2) matched_count = sum(1 for obj in data if obj["xkw_code"] != "0") inconsistent_count = sum(1 for obj in data if obj["xwk_code不为0但xkw_code与url_id不一致"] == 1) print(f"完成:共{len(data)}条,xkw_code非0共{matched_count}条,其中与url_id不一致{inconsistent_count}条,仍未匹配{len(still_unmatched)}条") if __name__ == "__main__": process(INPUT_JSON, EXCEL_PATH, STILL_UNMATCHED_JSON)