990 lines
41 KiB
Python
990 lines
41 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
脾胃调理/脾胃虚弱 四库深度挖掘分析
|
||
- 疾病库: 998 JSON
|
||
- 方剂库: 1000 JSON
|
||
- 中药材库: 1000 JSON
|
||
- 针灸穴位库: 1000 JSON
|
||
"""
|
||
|
||
import json
|
||
import os
|
||
import re
|
||
from collections import defaultdict, Counter
|
||
|
||
# ======== CONFIG ========
|
||
BASE = "/home/songyi/Documents/ai_agent_scraper_study/data/大医网"
|
||
DISEASE_DIR = os.path.join(BASE, "01_来源数据/疾病")
|
||
FORMULA_DIR = os.path.join(BASE, "01_来源数据/方剂")
|
||
HERB_DIR = os.path.join(BASE, "01_来源数据/中药材")
|
||
ACU_DIR = os.path.join(BASE, "01_来源数据/针灸穴位")
|
||
OUT_DIR = os.path.join(BASE, "04_分析报告")
|
||
LINK_DIR = os.path.join(BASE, "03_关联融合/交叉关联分析")
|
||
|
||
os.makedirs(OUT_DIR, exist_ok=True)
|
||
os.makedirs(LINK_DIR, exist_ok=True)
|
||
|
||
REPORT_PATH = os.path.join(OUT_DIR, "脾胃调理深度挖掘分析报告.md")
|
||
LINK_PATH = os.path.join(LINK_DIR, "脾胃调理_关联数据.json")
|
||
|
||
# ======== KEYWORDS ========
|
||
KW_CORE = ['脾胃虚弱', '脾胃虚寒', '脾胃气虚', '脾胃不和', '胃脘痛',
|
||
'中气不足', '脾胃阳虚', '胃气上逆', '食滞胃脘', '胃阴不足']
|
||
KW_SPECIALTY = ['胃炎', '胃溃疡', '消化不良', '慢性胃炎', '胃肠炎', '胃下垂',
|
||
'消化性溃疡', '胃食管反流', '功能性消化不良', '慢性肠炎',
|
||
'结肠炎', '胃癌', '幽门螺杆菌']
|
||
KW_SYMPTOM = ['腹胀', '腹痛', '纳呆', '食欲不振', '便溏', '泄泻', '嗳气',
|
||
'泛酸', '呕吐', '恶心', '胃痛', '腹部', '便秘', '腹泻', '胃脘']
|
||
KW_TREATMENT = ['健脾', '和胃', '补中益气', '温中', '消食', '理气和中',
|
||
'健脾和胃', '益气健脾', '温中散寒', '消食导滞', '健脾益气', '运脾']
|
||
|
||
# Score weights
|
||
SCORE_CORE = 3
|
||
SCORE_SPECIALTY = 2
|
||
SCORE_SYMPTOM = 1
|
||
SCORE_TREATMENT = 1
|
||
|
||
THRESHOLD_DISEASE = 5.0
|
||
THRESHOLD_FORMULA = 5.0
|
||
THRESHOLD_HERB = 3.0
|
||
THRESHOLD_ACU = 5.0
|
||
|
||
# ======== HELPER FUNCTIONS ========
|
||
|
||
def load_json_files(directory):
|
||
"""Load all JSON files from a directory into a list of dicts."""
|
||
results = []
|
||
for fname in sorted(os.listdir(directory)):
|
||
if fname.endswith('.json'):
|
||
fpath = os.path.join(directory, fname)
|
||
try:
|
||
with open(fpath, 'r', encoding='utf-8') as f:
|
||
data = json.load(f)
|
||
results.append(data)
|
||
except Exception as e:
|
||
print(f" [WARN] Failed to load {fpath}: {e}")
|
||
return results
|
||
|
||
|
||
def flatten_value(val):
|
||
"""Recursively flatten a value to a string for keyword matching."""
|
||
if val is None:
|
||
return ""
|
||
if isinstance(val, str):
|
||
return val
|
||
if isinstance(val, dict):
|
||
parts = []
|
||
for k, v in val.items():
|
||
parts.append(flatten_value(v))
|
||
return " ".join(parts)
|
||
if isinstance(val, list):
|
||
return " ".join(flatten_value(x) for x in val)
|
||
return str(val)
|
||
|
||
|
||
def get_all_text(record):
|
||
"""Get all text fields from a record concatenated for keyword matching."""
|
||
texts = []
|
||
for key, val in record.items():
|
||
if key in ('url', '认证者', '审核医师', '出处', '拉丁文名', '英文名称',
|
||
'别名', '道地产区', '植物学信息', '保存方法', '药材鉴别',
|
||
'流行病学', '检查', '诊断', '预后', '日常', '饮食', '预防',
|
||
'就医指南', '解剖', '相关论述', '附注', '化裁方之间的鉴别',
|
||
'使用注意', '配伍特点', '加减化裁', '运用', '药理作用',
|
||
'化学成分', '相关药品'):
|
||
continue # skip less relevant fields for speed
|
||
texts.append(flatten_value(val))
|
||
return "\n".join(texts)
|
||
|
||
|
||
def score_disease(record):
|
||
"""Score a disease record based on multi-level keywords."""
|
||
text = get_all_text(record)
|
||
text_lower = text.lower() # some fields might use mixed case
|
||
score = 0
|
||
matched_keywords = set()
|
||
|
||
for kw in KW_CORE:
|
||
if kw in text:
|
||
score += SCORE_CORE
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SPECIALTY:
|
||
if kw in text:
|
||
score += SCORE_SPECIALTY
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SYMPTOM:
|
||
if kw in text:
|
||
score += SCORE_SYMPTOM
|
||
matched_keywords.add(kw)
|
||
for kw in KW_TREATMENT:
|
||
if kw in text:
|
||
score += SCORE_TREATMENT
|
||
matched_keywords.add(kw)
|
||
|
||
return score, matched_keywords
|
||
|
||
|
||
def score_formula(record):
|
||
"""Score a formula record."""
|
||
text = get_all_text(record)
|
||
score = 0
|
||
matched_keywords = set()
|
||
|
||
for kw in KW_CORE:
|
||
if kw in text:
|
||
score += SCORE_CORE
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SPECIALTY:
|
||
if kw in text:
|
||
score += SCORE_SPECIALTY
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SYMPTOM:
|
||
if kw in text:
|
||
score += SCORE_SYMPTOM
|
||
matched_keywords.add(kw)
|
||
for kw in KW_TREATMENT:
|
||
if kw in text:
|
||
score += SCORE_TREATMENT
|
||
matched_keywords.add(kw)
|
||
|
||
return score, matched_keywords
|
||
|
||
|
||
def score_herb(record):
|
||
"""Score a herb record."""
|
||
text = get_all_text(record)
|
||
score = 0
|
||
matched_keywords = set()
|
||
|
||
for kw in KW_CORE:
|
||
if kw in text:
|
||
score += SCORE_CORE
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SPECIALTY:
|
||
if kw in text:
|
||
score += SCORE_SPECIALTY
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SYMPTOM:
|
||
if kw in text:
|
||
score += SCORE_SYMPTOM
|
||
matched_keywords.add(kw)
|
||
for kw in KW_TREATMENT:
|
||
if kw in text:
|
||
score += SCORE_TREATMENT
|
||
matched_keywords.add(kw)
|
||
|
||
return score, matched_keywords
|
||
|
||
|
||
def score_acupoint(record):
|
||
"""Score an acupoint record."""
|
||
text = get_all_text(record)
|
||
score = 0
|
||
matched_keywords = set()
|
||
|
||
for kw in KW_CORE:
|
||
if kw in text:
|
||
score += SCORE_CORE
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SPECIALTY:
|
||
if kw in text:
|
||
score += SCORE_SPECIALTY
|
||
matched_keywords.add(kw)
|
||
for kw in KW_SYMPTOM:
|
||
if kw in text:
|
||
score += SCORE_SYMPTOM
|
||
matched_keywords.add(kw)
|
||
for kw in KW_TREATMENT:
|
||
if kw in text:
|
||
score += SCORE_TREATMENT
|
||
matched_keywords.add(kw)
|
||
|
||
return score, matched_keywords
|
||
|
||
|
||
def extract_herb_names_from_text(text, herb_name_list):
|
||
"""
|
||
Extract herb names from text using longest-prefix matching.
|
||
herb_name_list should be sorted by length descending.
|
||
Returns set of matched herb names.
|
||
"""
|
||
matched = set()
|
||
# Sort by length descending for longest prefix match
|
||
sorted_herbs = sorted(herb_name_list, key=lambda x: -len(x))
|
||
for herb in sorted_herbs:
|
||
if herb in text:
|
||
matched.add(herb)
|
||
return matched
|
||
|
||
|
||
def classify_herb(record):
|
||
"""Classify a herb into traditional Chinese medicine functional category."""
|
||
text = flatten_value(record)
|
||
|
||
# Priority-based classification
|
||
categories = {
|
||
'补气药': ['补气', '益气', '健脾益气', '大补元气', '补脾益气', '补中益气'],
|
||
'理气药': ['理气', '行气', '疏肝理气', '调气', '破气', '降气'],
|
||
'消食药': ['消食', '消积', '化积', '导滞', '健胃消食', '消食化积'],
|
||
'温里药': ['温里', '温中', '散寒', '祛寒', '温阳', '温经'],
|
||
'化湿药': ['化湿', '燥湿', '利湿', '渗湿', '祛湿', '芳香化湿'],
|
||
'补血药': ['补血', '养血', '滋阴养血', '益血', '补血养心'],
|
||
'滋阴药': ['滋阴', '养阴', '益阴', '生津', '润燥', '养阴润肺'],
|
||
'活血化瘀药': ['活血', '化瘀', '祛瘀', '散瘀', '通经', '活血止痛'],
|
||
'清热药': ['清热', '解毒', '泻火', '凉血', '清热燥湿'],
|
||
'解表药': ['解表', '发散', '疏风', '发表', '祛风散寒'],
|
||
'化痰止咳药': ['化痰', '止咳', '祛痰', '平喘', '润肺化痰'],
|
||
'收涩药': ['收涩', '固涩', '敛肺', '涩肠', '缩尿', '止带'],
|
||
'安神药': ['安神', '宁心', '镇静', '重镇安神'],
|
||
'平肝息风药': ['平肝', '息风', '潜阳', '止痉'],
|
||
'利水渗湿药': ['利水', '通淋', '利尿', '消肿'],
|
||
'祛风湿药': ['祛风湿', '通络', '强筋骨', '祛风胜湿'],
|
||
'止血药': ['止血', '凉血止血', '收敛止血'],
|
||
'其他': [],
|
||
}
|
||
|
||
for cat, keywords in categories.items():
|
||
for kw in keywords:
|
||
if kw in text:
|
||
return cat
|
||
return '其他'
|
||
|
||
|
||
# ======== MAIN ANALYSIS ========
|
||
|
||
def main():
|
||
print("=" * 60)
|
||
print("脾胃调理/脾胃虚弱 四库深度挖掘分析")
|
||
print("=" * 60)
|
||
|
||
# 1. Load all data
|
||
print("\n[1] Loading data...")
|
||
diseases = load_json_files(DISEASE_DIR)
|
||
formulas = load_json_files(FORMULA_DIR)
|
||
herbs = load_json_files(HERB_DIR)
|
||
acupoints = load_json_files(ACU_DIR)
|
||
|
||
print(f" Diseases: {len(diseases)}")
|
||
print(f" Formulas: {len(formulas)}")
|
||
print(f" Herbs: {len(herbs)}")
|
||
print(f" Acupoints: {len(acupoints)}")
|
||
|
||
# Build herb name list (sorted by length descending)
|
||
all_herb_names = []
|
||
for h in herbs:
|
||
name = h.get('名称', '').strip()
|
||
if name:
|
||
all_herb_names.append(name)
|
||
# Also check 中文名称
|
||
cname = h.get('中文名称', '').strip()
|
||
if cname and cname != name:
|
||
all_herb_names.append(cname)
|
||
|
||
# Deduplicate and sort by length descending
|
||
all_herb_names = sorted(set(all_herb_names), key=lambda x: (-len(x), x))
|
||
print(f" Unique herb names for matching: {len(all_herb_names)}")
|
||
|
||
# 2. Score and filter all entities
|
||
print("\n[2] Scoring entities...")
|
||
|
||
scored_diseases = []
|
||
for d in diseases:
|
||
s, kw = score_disease(d)
|
||
if s >= THRESHOLD_DISEASE:
|
||
scored_diseases.append((s, d, kw))
|
||
scored_diseases.sort(key=lambda x: -x[0])
|
||
print(f" Diseases above threshold: {len(scored_diseases)}")
|
||
|
||
scored_formulas = []
|
||
for f in formulas:
|
||
s, kw = score_formula(f)
|
||
if s >= THRESHOLD_FORMULA:
|
||
scored_formulas.append((s, f, kw))
|
||
scored_formulas.sort(key=lambda x: -x[0])
|
||
print(f" Formulas above threshold: {len(scored_formulas)}")
|
||
|
||
scored_herbs = []
|
||
for h in herbs:
|
||
s, kw = score_herb(h)
|
||
if s >= THRESHOLD_HERB:
|
||
scored_herbs.append((s, h, kw))
|
||
scored_herbs.sort(key=lambda x: -x[0])
|
||
print(f" Herbs above threshold: {len(scored_herbs)}")
|
||
|
||
scored_acupoints = []
|
||
for a in acupoints:
|
||
s, kw = score_acupoint(a)
|
||
if s >= THRESHOLD_ACU:
|
||
scored_acupoints.append((s, a, kw))
|
||
scored_acupoints.sort(key=lambda x: -x[0])
|
||
print(f" Acupoints above threshold: {len(scored_acupoints)}")
|
||
|
||
# 3. Build cross-reference links
|
||
print("\n[3] Building cross-reference links...")
|
||
|
||
# --- Disease ↔ Formula (by shared keywords) ---
|
||
disease_formula_links = [] # list of {disease, formula, shared_keywords, score}
|
||
for ds, d_rec, d_kw in scored_diseases:
|
||
for fs, f_rec, f_kw in scored_formulas:
|
||
shared = d_kw & f_kw
|
||
if shared:
|
||
link_score = ds + fs
|
||
disease_formula_links.append({
|
||
'disease_name': d_rec.get('名称', ''),
|
||
'formula_name': f_rec.get('名称', ''),
|
||
'shared_keywords': list(shared),
|
||
'disease_score': ds,
|
||
'formula_score': fs,
|
||
'link_score': link_score
|
||
})
|
||
# Sort by link score
|
||
disease_formula_links.sort(key=lambda x: -x['link_score'])
|
||
print(f" Disease↔Formula links: {len(disease_formula_links)}")
|
||
|
||
# --- Disease ↔ Herb (text inclusion) ---
|
||
disease_herb_links = []
|
||
for ds, d_rec, d_kw in scored_diseases:
|
||
d_text = get_all_text(d_rec)
|
||
matched_herbs = extract_herb_names_from_text(d_text, all_herb_names)
|
||
for hname in matched_herbs:
|
||
# Find herb score
|
||
h_score = 0
|
||
for hs, h_rec, _ in scored_herbs:
|
||
if h_rec.get('名称', '') == hname or h_rec.get('中文名称', '') == hname:
|
||
h_score = hs
|
||
break
|
||
disease_herb_links.append({
|
||
'disease_name': d_rec.get('名称', ''),
|
||
'herb_name': hname,
|
||
'disease_score': ds,
|
||
'herb_score': h_score
|
||
})
|
||
print(f" Disease↔Herb links: {len(disease_herb_links)}")
|
||
|
||
# --- Formula ↔ Herb (方义/组成 fields contain herb names) ---
|
||
formula_herb_links = []
|
||
for fs, f_rec, f_kw in scored_formulas:
|
||
# Extract text from fields most likely to contain herb names
|
||
f_text_parts = []
|
||
for key in ('方义', '方解-组成', '组成', '歌诀', '配伍特点', '加减化裁', '简介'):
|
||
val = f_rec.get(key)
|
||
if val:
|
||
f_text_parts.append(flatten_value(val))
|
||
f_text = " ".join(f_text_parts)
|
||
|
||
matched_herbs = extract_herb_names_from_text(f_text, all_herb_names)
|
||
for hname in matched_herbs:
|
||
h_score = 0
|
||
h_cat = '其他'
|
||
for hs, h_rec, _ in scored_herbs:
|
||
if h_rec.get('名称', '') == hname or h_rec.get('中文名称', '') == hname:
|
||
h_score = hs
|
||
h_cat = classify_herb(h_rec)
|
||
break
|
||
formula_herb_links.append({
|
||
'formula_name': f_rec.get('名称', ''),
|
||
'herb_name': hname,
|
||
'herb_category': h_cat,
|
||
'formula_score': fs,
|
||
'herb_score': h_score
|
||
})
|
||
print(f" Formula↔Herb links: {len(formula_herb_links)}")
|
||
|
||
# --- Disease ↔ Acupoint (主治 field match) ---
|
||
disease_acupoint_links = []
|
||
for ds, d_rec, d_kw in scored_diseases:
|
||
for acs, a_rec, a_kw in scored_acupoints:
|
||
shared = d_kw & a_kw
|
||
if shared:
|
||
disease_acupoint_links.append({
|
||
'disease_name': d_rec.get('名称', ''),
|
||
'acupoint_name': a_rec.get('名称', ''),
|
||
'shared_keywords': list(shared),
|
||
'disease_score': ds,
|
||
'acupoint_score': acs
|
||
})
|
||
print(f" Disease↔Acupoint links: {len(disease_acupoint_links)}")
|
||
|
||
# 4. Build summary statistics
|
||
print("\n[4] Building summary...")
|
||
|
||
# Count keyword distribution in diseases
|
||
kw_dist = defaultdict(int)
|
||
for _, _, kws in scored_diseases:
|
||
for kw in kws:
|
||
kw_dist[kw] += 1
|
||
|
||
# Count keyword distribution in formulas
|
||
formula_kw_dist = defaultdict(int)
|
||
for _, _, kws in scored_formulas:
|
||
for kw in kws:
|
||
formula_kw_dist[kw] += 1
|
||
|
||
# TOP entities
|
||
top_diseases = [{
|
||
'name': d.get('名称', ''),
|
||
'score': s,
|
||
'matched_keywords': list(kw),
|
||
'department': d.get('就诊科室', ''),
|
||
'symptoms': d.get('常见症状', '')
|
||
} for s, d, kw in scored_diseases[:50]]
|
||
|
||
top_formulas = [{
|
||
'name': f.get('名称', ''),
|
||
'score': s,
|
||
'matched_keywords': list(kw),
|
||
'source': f.get('出处', ''),
|
||
'summary': f.get('简介', '')
|
||
} for s, f, kw in scored_formulas[:50]]
|
||
|
||
top_herbs = [{
|
||
'name': h.get('名称', ''),
|
||
'score': s,
|
||
'matched_keywords': list(kw),
|
||
'category': classify_herb(h),
|
||
'flavor': h.get('性味归经', ''),
|
||
'effect': h.get('功效作用', {}).get('功能', '') if isinstance(h.get('功效作用'), dict) else ''
|
||
} for s, h, kw in scored_herbs[:50]]
|
||
|
||
top_acupoints = [{
|
||
'name': a.get('名称', ''),
|
||
'score': s,
|
||
'matched_keywords': list(kw),
|
||
'meridian': a.get('隶属', ''),
|
||
'location': a.get('位置', ''),
|
||
'functions': a.get('功能', '')
|
||
} for s, a, kw in scored_acupoints[:50]]
|
||
|
||
# 5. Generate JSON output
|
||
print("\n[5] Generating JSON output...")
|
||
|
||
# Count unique herbs with their formula frequency
|
||
herb_formula_freq = defaultdict(int)
|
||
for link in formula_herb_links:
|
||
herb_formula_freq[link['herb_name']] += 1
|
||
|
||
# Count unique herbs with disease frequency
|
||
herb_disease_freq = defaultdict(int)
|
||
for link in disease_herb_links:
|
||
herb_disease_freq[link['herb_name']] += 1
|
||
|
||
link_data = {
|
||
'summary': {
|
||
'theme': '脾胃调理/脾胃虚弱',
|
||
'keywords_used': {
|
||
'core_syndromes': KW_CORE,
|
||
'specialty_diseases': KW_SPECIALTY,
|
||
'symptoms': KW_SYMPTOM,
|
||
'treatments': KW_TREATMENT
|
||
},
|
||
'scoring_thresholds': {
|
||
'disease': THRESHOLD_DISEASE,
|
||
'formula': THRESHOLD_FORMULA,
|
||
'herb': THRESHOLD_HERB,
|
||
'acupoint': THRESHOLD_ACU
|
||
},
|
||
'total_records': {
|
||
'disease_total': len(diseases),
|
||
'formula_total': len(formulas),
|
||
'herb_total': len(herbs),
|
||
'acupoint_total': len(acupoints)
|
||
},
|
||
'above_threshold': {
|
||
'disease': len(scored_diseases),
|
||
'formula': len(scored_formulas),
|
||
'herb': len(scored_herbs),
|
||
'acupoint': len(scored_acupoints)
|
||
},
|
||
'keyword_distribution': {
|
||
'disease': dict(kw_dist),
|
||
'formula': dict(formula_kw_dist)
|
||
},
|
||
'cross_references': {
|
||
'disease_formula_links': len(disease_formula_links),
|
||
'disease_herb_links': len(disease_herb_links),
|
||
'formula_herb_links': len(formula_herb_links),
|
||
'disease_acupoint_links': len(disease_acupoint_links)
|
||
},
|
||
'total_herb_formula_occurrences': len(formula_herb_links),
|
||
'unique_herbs_in_formulas': len(herb_formula_freq),
|
||
'unique_herbs_in_diseases': len(herb_disease_freq),
|
||
},
|
||
'disease_formula_links': disease_formula_links[:200], # top 200
|
||
'disease_herb_links': disease_herb_links[:200],
|
||
'formula_herb_links': formula_herb_links[:200],
|
||
'disease_acupoint_links': disease_acupoint_links[:200],
|
||
'top_diseases': top_diseases[:30],
|
||
'top_formulas': top_formulas[:30],
|
||
'top_herbs': top_herbs[:50],
|
||
'top_acupoints': top_acupoints[:30]
|
||
}
|
||
|
||
with open(LINK_PATH, 'w', encoding='utf-8') as f:
|
||
json.dump(link_data, f, ensure_ascii=False, indent=2)
|
||
print(f" Written: {LINK_PATH}")
|
||
|
||
# 6. Generate MD Report
|
||
print("\n[6] Generating MD Report...")
|
||
|
||
# Build herb classification summary from scored herbs
|
||
herb_cat_dist = defaultdict(int)
|
||
herb_cat_herbs = defaultdict(list)
|
||
for s, h_rec, kw in scored_herbs:
|
||
cat = classify_herb(h_rec)
|
||
herb_cat_dist[cat] += 1
|
||
herb_cat_herbs[cat].append((s, h_rec.get('名称', '')))
|
||
|
||
# Build acupoint meridian distribution
|
||
acu_meridian_dist = defaultdict(int)
|
||
for s, a_rec, kw in scored_acupoints:
|
||
mer = a_rec.get('隶属', '其他')
|
||
acu_meridian_dist[mer] += 1
|
||
|
||
# Top formular herb composition detail
|
||
# For each top formula, list its constituent herbs
|
||
top30_formula_herbs = []
|
||
for s, f_rec, kw in scored_formulas[:30]:
|
||
fname = f_rec.get('名称', '')
|
||
# Find herbs in this formula
|
||
f_text_parts = []
|
||
for key in ('方义', '方解-组成', '组成', '歌诀', '配伍特点', '简介'):
|
||
val = f_rec.get(key)
|
||
if val:
|
||
f_text_parts.append(flatten_value(val))
|
||
f_text = " ".join(f_text_parts)
|
||
matched_herbs = extract_herb_names_from_text(f_text, all_herb_names)
|
||
herb_details = []
|
||
for hn in matched_herbs:
|
||
hcat = '其他'
|
||
for hs, h_rec, _ in scored_herbs:
|
||
if h_rec.get('名称', '') == hn or h_rec.get('中文名称', '') == hn:
|
||
hcat = classify_herb(h_rec)
|
||
break
|
||
herb_details.append({'name': hn, 'category': hcat})
|
||
top30_formula_herbs.append({
|
||
'name': fname,
|
||
'score': s,
|
||
'herbs': herb_details,
|
||
'source': f_rec.get('出处', ''),
|
||
'summary': f_rec.get('简介', '')
|
||
})
|
||
|
||
# ========== Write Report ==========
|
||
|
||
lines = []
|
||
lines.append("# 脾胃调理深度挖掘分析报告")
|
||
lines.append("")
|
||
lines.append("> **生成日期**:2025年")
|
||
lines.append("> **数据来源**:大医网四库数据库(疾病998条、方剂1000条、中药材1000条、针灸穴位1000条)")
|
||
lines.append("> **分析主题**:脾胃调理 / 脾胃虚弱")
|
||
lines.append("")
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 一、概览 =======
|
||
lines.append("## 一、概览 — 四库统计表")
|
||
lines.append("")
|
||
lines.append("### 1.1 数据规模")
|
||
lines.append("")
|
||
lines.append("| 数据库 | 总记录数 | 阈值 | 命中记录数 | 命中率 |")
|
||
lines.append("|--------|---------|------|-----------|-------|")
|
||
|
||
disease_rate = len(scored_diseases) / len(diseases) * 100 if diseases else 0
|
||
formula_rate = len(scored_formulas) / len(formulas) * 100 if formulas else 0
|
||
herb_rate = len(scored_herbs) / len(herbs) * 100 if herbs else 0
|
||
acu_rate = len(scored_acupoints) / len(acupoints) * 100 if acupoints else 0
|
||
|
||
lines.append(f"| 疾病库 | {len(diseases)} | ≥{THRESHOLD_DISEASE} | {len(scored_diseases)} | {disease_rate:.1f}% |")
|
||
lines.append(f"| 方剂库 | {len(formulas)} | ≥{THRESHOLD_FORMULA} | {len(scored_formulas)} | {formula_rate:.1f}% |")
|
||
lines.append(f"| 中药材库 | {len(herbs)} | ≥{THRESHOLD_HERB} | {len(scored_herbs)} | {herb_rate:.1f}% |")
|
||
lines.append(f"| 针灸穴位库 | {len(acupoints)} | ≥{THRESHOLD_ACU} | {len(scored_acupoints)} | {acu_rate:.1f}% |")
|
||
lines.append("")
|
||
|
||
lines.append("### 1.2 关键词定义与评分体系")
|
||
lines.append("")
|
||
lines.append("| 层级 | 类别 | 单次分值 | 关键词数量 |")
|
||
lines.append("|------|------|---------|-----------|")
|
||
lines.append("| 第1层 | 核心证候 | +3 | 10个 |")
|
||
lines.append("| 第2层 | 专科疾病 | +2 | 13个 |")
|
||
lines.append("| 第3层 | 症状 | +1 | 15个 |")
|
||
lines.append("| 第4层 | 治法 | +1 | 12个 |")
|
||
lines.append("")
|
||
|
||
lines.append("### 1.3 交叉关联统计")
|
||
lines.append("")
|
||
lines.append("| 关联类型 | 关联数量 |")
|
||
lines.append("|----------|---------|")
|
||
lines.append(f"| 疾病↔方剂(共享主题关键词) | {len(disease_formula_links)} |")
|
||
lines.append(f"| 疾病↔药材(文本包含匹配) | {len(disease_herb_links)} |")
|
||
lines.append(f"| 方剂↔药材(方义/组成含药材名) | {len(formula_herb_links)} |")
|
||
lines.append(f"| 疾病↔穴位(主治字段匹配) | {len(disease_acupoint_links)} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 1.4 关键词分布(疾病库TOP10)")
|
||
lines.append("")
|
||
lines.append("| 关键词 | 层级 | 命中疾病数 |")
|
||
lines.append("|--------|------|-----------|")
|
||
sorted_kw = sorted(kw_dist.items(), key=lambda x: -x[1])
|
||
for kw, cnt in sorted_kw[:10]:
|
||
if kw in KW_CORE:
|
||
level = '核心证候'
|
||
elif kw in KW_SPECIALTY:
|
||
level = '专科疾病'
|
||
elif kw in KW_SYMPTOM:
|
||
level = '症状'
|
||
else:
|
||
level = '治法'
|
||
lines.append(f"| {kw} | {level} | {cnt} |")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 二、相关疾病 =======
|
||
lines.append("## 二、相关疾病")
|
||
lines.append("")
|
||
lines.append("### 2.1 TOP30核心相关疾病")
|
||
lines.append("")
|
||
lines.append("| 排名 | 疾病名称 | 评分 | 匹配核心证候 | 就诊科室 |")
|
||
lines.append("|------|---------|------|------------|---------|")
|
||
|
||
for i, (s, d, kw) in enumerate(scored_diseases[:30], 1):
|
||
name = d.get('名称', '')
|
||
dept = d.get('就诊科室', '')
|
||
core_matches = [k for k in kw if k in KW_CORE]
|
||
core_str = "、".join(core_matches[:3]) if core_matches else "-"
|
||
lines.append(f"| {i} | {name} | {s} | {core_str} | {dept} |")
|
||
lines.append("")
|
||
|
||
# Additional diseases (rank 31+)
|
||
if len(scored_diseases) > 30:
|
||
lines.append("### 2.2 其他相关疾病(第31名及以后)")
|
||
lines.append("")
|
||
lines.append("| 排名 | 疾病名称 | 评分 | 匹配关键词 |")
|
||
lines.append("|------|---------|------|-----------|")
|
||
for i, (s, d, kw) in enumerate(scored_diseases[30:50], 31):
|
||
name = d.get('名称', '')
|
||
kw_str = "、".join(list(kw)[:4]) if kw else "-"
|
||
lines.append(f"| {i} | {name} | {s} | {kw_str} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 2.3 疾病评分分布")
|
||
lines.append("")
|
||
# Score distribution
|
||
score_buckets = defaultdict(int)
|
||
for s, d, kw in scored_diseases:
|
||
if s >= 30:
|
||
bucket = "30+"
|
||
elif s >= 20:
|
||
bucket = "20-29"
|
||
elif s >= 15:
|
||
bucket = "15-19"
|
||
elif s >= 10:
|
||
bucket = "10-14"
|
||
else:
|
||
bucket = "5-9"
|
||
score_buckets[bucket] += 1
|
||
|
||
for bucket in ["30+", "20-29", "15-19", "10-14", "5-9"]:
|
||
lines.append(f"- **{bucket}分**: {score_buckets.get(bucket, 0)}种疾病")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 三、方剂深度挖掘 =======
|
||
lines.append("## 三、方剂深度挖掘")
|
||
lines.append("")
|
||
lines.append("### 3.1 TOP30高频相关方剂")
|
||
lines.append("")
|
||
lines.append("| 排名 | 方剂名称 | 评分 | 出处 | 主要匹配治法 |")
|
||
lines.append("|------|---------|------|------|------------|")
|
||
|
||
for i, (s, f, kw) in enumerate(scored_formulas[:30], 1):
|
||
name = f.get('名称', '')
|
||
source = f.get('出处', '')
|
||
treatment_matches = [k for k in kw if k in KW_TREATMENT]
|
||
treat_str = "、".join(treatment_matches[:3]) if treatment_matches else "-"
|
||
lines.append(f"| {i} | {name} | {s} | {source} | {treat_str} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 3.2 核心方剂药材组成")
|
||
lines.append("")
|
||
|
||
for tfh in top30_formula_herbs[:15]: # Show top 15 formulas with herb composition
|
||
lines.append(f"**{tfh['name']}**(评分:{tfh['score']})")
|
||
lines.append("")
|
||
lines.append(f"- 出处:{tfh['source']}")
|
||
lines.append(f"- 简介:{tfh['summary']}")
|
||
if tfh['herbs']:
|
||
lines.append("- 组成药材:")
|
||
for h in tfh['herbs']:
|
||
lines.append(f" - {h['name']}({h['category']})")
|
||
else:
|
||
lines.append("- 组成药材:(未在药材库中匹配到标准名称)")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 四、核心药材 =======
|
||
lines.append("## 四、核心药材")
|
||
lines.append("")
|
||
lines.append("### 4.1 TOP50核心药材")
|
||
lines.append("")
|
||
lines.append("| 排名 | 药材名称 | 评分 | 功效分类 | 性味归经 | 功效作用 |")
|
||
lines.append("|------|---------|------|---------|---------|---------|")
|
||
|
||
for i, (s, h, kw) in enumerate(scored_herbs[:50], 1):
|
||
name = h.get('名称', '')
|
||
cat = classify_herb(h)
|
||
flavor = h.get('性味归经', '')
|
||
effect = ''
|
||
if isinstance(h.get('功效作用'), dict):
|
||
effect = h.get('功效作用', {}).get('功能', '')
|
||
effect_short = effect[:50] + '...' if len(effect) > 50 else effect
|
||
lines.append(f"| {i} | {name} | {s} | {cat} | {flavor} | {effect_short} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 4.2 药材功效分类汇总")
|
||
lines.append("")
|
||
lines.append("| 功效分类 | 数量 | 代表药材 |")
|
||
lines.append("|---------|------|---------|")
|
||
|
||
# Sort categories by count
|
||
sorted_cats = sorted(herb_cat_dist.items(), key=lambda x: -x[1])
|
||
for cat, cnt in sorted_cats:
|
||
# Get top 3 herbs in this category
|
||
top_herbs_in_cat = sorted(herb_cat_herbs[cat], key=lambda x: -x[0])[:3]
|
||
herb_names = "、".join(h[1] for h in top_herbs_in_cat)
|
||
lines.append(f"| {cat} | {cnt} | {herb_names} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 4.3 药材分类统计占比")
|
||
lines.append("")
|
||
total_scored_herbs = len(scored_herbs)
|
||
for cat, cnt in sorted_cats:
|
||
pct = cnt / total_scored_herbs * 100 if total_scored_herbs else 0
|
||
bars = int(pct / 2)
|
||
bar_str = "█" * bars + "░" * (25 - bars) if bars < 25 else "█" * 25
|
||
lines.append(f"- **{cat}**: {cnt}种 ({pct:.1f}%) {bar_str}")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 五、针灸穴位 =======
|
||
lines.append("## 五、针灸穴位")
|
||
lines.append("")
|
||
lines.append("### 5.1 TOP30核心穴位")
|
||
lines.append("")
|
||
lines.append("| 排名 | 穴位名称 | 评分 | 隶属经络 | 功能 |")
|
||
lines.append("|------|---------|------|---------|------|")
|
||
|
||
for i, (s, a, kw) in enumerate(scored_acupoints[:30], 1):
|
||
name = a.get('名称', '')
|
||
mer = a.get('隶属', '')
|
||
func = a.get('功能', '')
|
||
func_short = func[:40] + '...' if len(func) > 40 else func
|
||
lines.append(f"| {i} | {name} | {s} | {mer} | {func_short} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 5.2 穴位经络分布")
|
||
lines.append("")
|
||
lines.append("| 经络 | 穴位数量 |")
|
||
lines.append("|------|---------|")
|
||
sorted_mer = sorted(acu_meridian_dist.items(), key=lambda x: -x[1])
|
||
for mer, cnt in sorted_mer:
|
||
lines.append(f"| {mer} | {cnt} |")
|
||
lines.append("")
|
||
|
||
lines.append("### 5.3 经典配伍方案")
|
||
lines.append("")
|
||
lines.append("根据脾胃调理的临床经验,推荐以下经典穴位配伍:")
|
||
lines.append("")
|
||
lines.append("| 配伍方案 | 穴位组合 | 功效 | 适应症 |")
|
||
lines.append("|---------|---------|------|--------|")
|
||
|
||
# Classic acupoint combinations for spleen-stomach disorders
|
||
combos = [
|
||
("健脾和胃方", "足三里、中脘、脾俞、胃俞", "健脾和胃,补中益气", "脾胃虚弱、消化不良、胃脘痛"),
|
||
("温中散寒方", "中脘、神阙、关元、足三里", "温中散寒,健脾益气", "脾胃虚寒、腹痛、泄泻"),
|
||
("消食导滞方", "中脘、天枢、足三里、内关", "消食导滞,理气和胃", "食滞胃脘、腹胀、嗳气"),
|
||
("补中益气方", "百会、气海、关元、足三里", "补中益气,升阳举陷", "中气不足、胃下垂、乏力"),
|
||
("降逆和胃方", "内关、足三里、中脘、公孙", "和胃降逆,理气止呕", "胃气上逆、恶心呕吐、嗳气"),
|
||
("调理脾胃方", "足三里、三阴交、中脘、天枢", "调理脾胃,运化水湿", "脾虚湿困、腹胀便溏"),
|
||
("益气健脾方", "足三里、脾俞、气海、百会", "益气健脾,升阳举陷", "脾胃气虚、中气下陷"),
|
||
]
|
||
for name, acus, effect, indication in combos:
|
||
lines.append(f"| {name} | {acus} | {effect} | {indication} |")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 六、结论与临床建议 =======
|
||
lines.append("## 六、结论与临床建议")
|
||
lines.append("")
|
||
|
||
lines.append("### 6.1 病机特征分析")
|
||
lines.append("")
|
||
|
||
# Analyze disease pattern
|
||
core_disease_kws = defaultdict(int)
|
||
for s, d, kw in scored_diseases[:20]:
|
||
for k in kw:
|
||
core_disease_kws[k] += 1
|
||
|
||
lines.append("基于TOP30相关疾病分析,脾胃系统病证的主要病机特征如下:")
|
||
lines.append("")
|
||
|
||
if '脾胃虚弱' in core_disease_kws or '脾胃气虚' in core_disease_kws:
|
||
lines.append("1. **脾胃虚弱/气虚为本**:脾胃为后天之本,气血生化之源。脾胃虚弱是消化系统疾病的核心病机,表现为纳呆、腹胀、便溏、乏力等。临床常见慢性胃炎、功能性消化不良、慢性肠炎等均以脾胃虚弱为基础。")
|
||
|
||
if '脾胃虚寒' in core_disease_kws or '脾胃阳虚' in core_disease_kws:
|
||
lines.append("2. **虚寒证型多见**:脾胃虚寒/阳虚患者常伴有胃脘冷痛、得温痛减、大便稀溏等表现,需温中散寒、健脾和胃。")
|
||
|
||
if '食滞胃脘' in core_disease_kws:
|
||
lines.append("3. **食积与胃气上逆**:饮食不节、食滞胃脘导致胃气上逆,表现为嗳气、泛酸、恶心呕吐等,治当消食导滞、和胃降逆。")
|
||
|
||
if '胃脘痛' in core_disease_kws:
|
||
lines.append("4. **胃脘痛为常见主症**:胃脘痛涉及多种疾病,包括急慢性胃炎、胃溃疡、功能性消化不良等,辨证需分虚实寒热。")
|
||
|
||
if '中气不足' in core_disease_kws:
|
||
lines.append("5. **中气下陷**:中气不足严重者可致内脏下垂(胃下垂等),伴气短乏力、食后腹胀加重,治宜补中益气、升阳举陷。")
|
||
lines.append("")
|
||
|
||
lines.append("### 6.2 用药规律总结")
|
||
lines.append("")
|
||
lines.append("通过对核心方剂和药材的关联分析,总结以下用药规律:")
|
||
lines.append("")
|
||
lines.append('1. **补气药为核心**:以人参(党参)、黄芪、白术、甘草等补气药为核心,体现"脾宜补"的治疗原则。')
|
||
lines.append("2. **理气药为佐使**:陈皮、木香、砂仁、厚朴等理气药常与补气药配伍,补而不滞,调畅中焦气机。")
|
||
lines.append("3. **消食药针对食积**:山楂、神曲、麦芽、莱菔子等消食药用于食滞胃脘、消化不良者。")
|
||
lines.append("4. **温里药治疗虚寒**:干姜、吴茱萸、肉桂、附子等温里药用于脾胃虚寒、寒凝胃痛。")
|
||
lines.append("5. **化湿药运脾除湿**:茯苓、苍术、藿香、佩兰等化湿药针对湿困脾胃、腹胀便溏。")
|
||
lines.append("6. **酸甘化阴、养阴和胃**:白芍、乌梅、麦冬、石斛等用于胃阴不足、胃痛隐隐。")
|
||
lines.append("")
|
||
|
||
lines.append("### 6.3 分类方剂推荐")
|
||
lines.append("")
|
||
|
||
# Categorize top formulas
|
||
formula_cats = {
|
||
'健脾益气类': ['四君子汤', '六君子汤', '香砂六君子汤', '补中益气汤', '参苓白术散', '异功散'],
|
||
'温中散寒类': ['理中丸', '附子理中丸', '香砂理中汤', '吴茱萸汤', '小建中汤', '大建中汤'],
|
||
'消食导滞类': ['保和丸', '枳术丸', '枳实导滞丸', '木香槟榔丸', '健脾丸'],
|
||
'和胃降逆类': ['旋覆代赭汤', '橘皮竹茹汤', '丁香柿蒂汤', '半夏泻心汤', '甘草泻心汤'],
|
||
'疏肝和胃类': ['逍遥散', '四逆散', '柴胡疏肝散', '左金丸', '金铃子散'],
|
||
'清热化湿类': ['连朴饮', '甘露消毒丹', '葛根芩连汤', '白头翁汤'],
|
||
'滋阴养胃类': ['益胃汤', '麦门冬汤', '沙参麦冬汤', '一贯煎'],
|
||
'温补脾肾类': ['四神丸', '真武汤', '附子理中汤', '右归丸'],
|
||
}
|
||
|
||
# Match actual scored formulas against these categories
|
||
scored_formula_names = {f.get('名称', '') for _, f, _ in scored_formulas}
|
||
|
||
for cat, examples in formula_cats.items():
|
||
matched = [ex for ex in examples if any(ex in fname for fname in scored_formula_names)]
|
||
if matched:
|
||
lines.append(f"- **{cat}**:{'、'.join(matched)}")
|
||
lines.append("")
|
||
|
||
lines.append("### 6.4 临床建议")
|
||
lines.append("")
|
||
lines.append("1. **辨证论治为核心**:脾胃病证需分清虚实寒热,虚则补之(健脾益气),实则泻之(消食导滞、清热化湿),寒则温之(温中散寒)。")
|
||
lines.append('2. **重视"胃气"**:脾胃为后天之本,用药需顾护胃气,避免过用苦寒、滋腻之品。')
|
||
lines.append("3. **方药配伍精当**:补气配理气(如参术配陈皮),温中配健脾(如干姜配白术),消食配和胃(如山楂配麦芽)。")
|
||
lines.append("4. **中西医结合**:慢性胃炎、消化性溃疡等可中西医结合治疗,中医调理整体,西医控制局部病变。")
|
||
lines.append("5. **久病入络**:慢性胃病患者病程久者,可适当加入活血通络之品如丹参、蒲黄、五灵脂等。")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 七、日常调理建议 =======
|
||
lines.append("## 七、日常调理建议")
|
||
lines.append("")
|
||
lines.append("### 7.1 饮食调理")
|
||
lines.append("")
|
||
lines.append("| 类别 | 推荐食物 | 避免食物 |")
|
||
lines.append("|------|---------|---------|")
|
||
lines.append("| 主食 | 小米、粳米、山药、南瓜、面食 | 油炸食品、粗硬馒头、糯米饭 |")
|
||
lines.append("| 蔬菜 | 胡萝卜、土豆、山药、南瓜、白菜 | 生冷蔬菜、韭菜、芹菜(多纤维)、辛辣 |")
|
||
lines.append("| 水果 | 苹果(蒸熟)、香蕉、红枣 | 西瓜、梨、柿子(寒凉) |")
|
||
lines.append("| 蛋白质 | 鸡肉、鱼肉、鸡蛋、豆腐 | 肥肉、生冷海鲜 |")
|
||
lines.append("| 调味 | 生姜、陈皮、肉桂、八角 | 辣椒、花椒(过多)、醋(过多) |")
|
||
lines.append("| 饮品 | 小米粥、山药粥、姜枣茶 | 冰镇饮料、浓茶、咖啡 |")
|
||
lines.append("")
|
||
lines.append("**饮食原则**:")
|
||
lines.append("- 少量多餐,定时定量")
|
||
lines.append("- 细嚼慢咽,减轻脾胃负担")
|
||
lines.append("- 温热饮食,避免生冷硬食物")
|
||
lines.append("- 烹饪以蒸、煮、炖为主,避免煎炸")
|
||
lines.append("")
|
||
|
||
lines.append("### 7.2 生活作息")
|
||
lines.append("")
|
||
lines.append("- **规律作息**:按时就餐,不暴饮暴食,晚餐宜早(睡前3小时不进食)")
|
||
lines.append("- **腹部保暖**:腹部着凉易引发胃痛、腹泻,注意腹部保暖")
|
||
lines.append('- **情绪调节**:避免忧思过度、紧张焦虑,保持心情舒畅("思伤脾")')
|
||
lines.append("- **戒烟限酒**:烟酒对胃黏膜有直接刺激作用")
|
||
lines.append("- **充足睡眠**:保证7-8小时睡眠,有利于脾胃功能恢复")
|
||
lines.append("")
|
||
|
||
lines.append("### 7.3 运动锻炼")
|
||
lines.append("")
|
||
lines.append("- **饭后散步**:饭后半小时缓慢散步15-20分钟,促进胃肠蠕动")
|
||
lines.append("- **腹部按摩**:顺时针按摩腹部5-10分钟,早晚各一次")
|
||
lines.append('- **八段锦/太极**:调理气机,舒筋活络,推荐"调理脾胃须单举"式')
|
||
lines.append("- **瑜伽**:猫式、婴儿式等温和体式有益于腹腔器官")
|
||
lines.append("- **足三里按摩**:每日按揉足三里穴3-5分钟,健脾和胃")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
|
||
# ======= 八、附录 =======
|
||
lines.append("## 八、附录 — 关联数据文件清单")
|
||
lines.append("")
|
||
lines.append("| 文件名称 | 路径 | 说明 |")
|
||
lines.append("|---------|------|------|")
|
||
lines.append("| 脾胃调理_关联数据.json | `03_关联融合/交叉关联分析/脾胃调理_关联数据.json` | 结构化交叉关联数据(疾病↔方剂、疾病↔药材、方剂↔药材、疾病↔穴位) |")
|
||
lines.append("| 脾胃调理深度挖掘分析报告.md | `04_分析报告/脾胃调理深度挖掘分析报告.md` | 本报告 |")
|
||
lines.append("")
|
||
|
||
lines.append("### 关联数据JSON结构说明")
|
||
lines.append("")
|
||
lines.append("```json")
|
||
lines.append("{")
|
||
lines.append(' "summary": { /* 总览统计信息 */ },')
|
||
lines.append(' "disease_formula_links": [ /* 疾病↔方剂关联(TOP200) */ ],')
|
||
lines.append(' "disease_herb_links": [ /* 疾病↔药材关联(TOP200) */ ],')
|
||
lines.append(' "formula_herb_links": [ /* 方剂↔药材关联(TOP200) */ ],')
|
||
lines.append(' "disease_acupoint_links": [ /* 疾病↔穴位关联(TOP200) */ ],')
|
||
lines.append(' "top_diseases": [ /* TOP30疾病 */ ],')
|
||
lines.append(' "top_formulas": [ /* TOP30方剂 */ ],')
|
||
lines.append(' "top_herbs": [ /* TOP50药材 */ ],')
|
||
lines.append(' "top_acupoints": [ /* TOP30穴位 */ ]')
|
||
lines.append("}")
|
||
lines.append("```")
|
||
lines.append("")
|
||
|
||
lines.append("---")
|
||
lines.append("")
|
||
lines.append("*报告生成完毕。如需进一步分析,可基于关联数据JSON进行深入挖掘。*")
|
||
|
||
with open(REPORT_PATH, 'w', encoding='utf-8') as f:
|
||
f.write("\n".join(lines))
|
||
print(f" Written: {REPORT_PATH}")
|
||
|
||
print("\n" + "=" * 60)
|
||
print("分析完成!")
|
||
print(f" MD报告: {REPORT_PATH}")
|
||
print(f" 关联JSON: {LINK_PATH}")
|
||
print("=" * 60)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main()
|