初始归档:健康管理资料库(大医网/药膳/体质监测/中医理论等12个资料集,7712个文件)

This commit is contained in:
512song committed 2026-09-23 21:59:25 +08:00
commit 80ae3811cf
7712 files changed
+4628547

No files matched your search

@@ -0,0 +1,212 @@
#!/usr/bin/env python3
"""
国家学生体质健康标准(2014年修订)— 评分数据提取脚本
教育部发布,适用于全日制小学至大学学生
满分120分制(100基础分 + 20附加分)
"""
import json, os, re, sys
from docx import Document
BASE = '/home/songyi/Documents/ai_agent_scraper_study/data/国家学生体质健康标准'
DOCX = os.path.join(BASE, '01_来源数据/国家学生体质健康标准(2014年修订).docx')
def parse_range(val):
"""解析值域:'13.5~18.1', '≤13.4', '≥17.9'"""
val = val.strip().replace(' ', '').replace('\n','')
if re.match(r'[≥>]=?\s*([\d.]+)', val):
m = re.match(r'[≥>]=?\s*([\d.]+)', val)
return {"min": float(m.group(1))}
if re.match(r'[≤<]=?\s*([\d.]+)', val):
m = re.match(r'[≤<]=?\s*([\d.]+)', val)
return {"max": float(m.group(1))}
if re.match(r'([\d.]+)\s*[~-]\s*([\d.]+)', val):
m = re.match(r'([\d.]+)\s*[~-]\s*([\d.]+)', val)
lo, hi = float(m.group(1)), float(m.group(2))
return {"min": min(lo, hi), "max": max(lo, hi)}
if re.match(r'(\d+)[::·]\s*(\d+[\']?[\d.]*)', val):
m = re.match(r'(\d+)[::·]\s*(\d+[\']?[\d.]*)', val)
minutes = int(m.group(1))
rest = m.group(2).replace("'", ".")
seconds = float(rest) if '.' in rest else int(rest)
return {"exact": minutes * 60 + seconds}
if re.match(r'^([\d.]+)$', val):
m = re.match(r'^([\d.]+)$', val)
return {"exact": float(m.group(1))}
return {"raw": val}
def extract_all():
doc = Document(DOCX)
result = {
'metadata': {
'title': '国家学生体质健康标准(2014年修订)',
'publisher': '教育部',
'year': 2014,
'total_tables': len(doc.tables),
'scoring_system': '100分基础 + 20分附加 = 120分满分',
'rating_levels': {
'优秀': {'min': 90.0},
'良好': {'min': 80.0, 'max': 89.9},
'及格': {'min': 60.0, 'max': 79.9},
'不及格': {'max': 59.9}
}
},
'weight_table': {},
'scoring_tables': [],
'bonus_tables': [],
'registration_tables': []
}
for i, table in enumerate(doc.tables):
rows_data = []
for row in table.rows:
cells = [cell.text.strip().replace('\n', ' ') for cell in row.cells]
rows_data.append(cells)
if not rows_data:
continue
header = rows_data[0]
header_str = ' '.join(str(h) for h in header).strip()
# 权重表(表0)
if i == 0:
for row in rows_data[1:]:
if len(row) >= 3:
obj = row[0].strip()
indicator = row[1].strip()
weight = row[2].strip()
try:
w = float(weight)
result['weight_table'].setdefault(obj, {})[indicator] = w
except ValueError:
pass
continue
# 登记卡表
if '学校签章' in header_str or ('姓名' in header_str and '性别' in header_str):
result['registration_tables'].append({
'table_index': i, 'rows': len(rows_data), 'cols': len(header)
})
continue
# 判断加分表
is_bonus = '加分' in header_str and '成绩' not in header_str
# 解析年级列
grade_cols = []
start_col = 1 if is_bonus else 2
for ci, h in enumerate(header):
h_clean = h.strip().replace('\n', ' ')
if h_clean and ci >= start_col:
# 跳过'单项得分'列
if '单项' in h_clean or '得分' in h_clean:
continue
grade_cols.append((ci, h_clean))
if not grade_cols:
continue
table_info = {
'table_index': i,
'header_sample': [h.strip() for h in header[:5]],
'grade_names': [g[1] for g in grade_cols],
'type': 'bonus' if is_bonus else 'standard',
'rows_count': len(rows_data) - 1,
'data': []
}
for row in rows_data[1:]:
if is_bonus:
if len(row) < 2:
continue
bonus_str = row[0].strip()
try:
bonus_score = int(bonus_str) if bonus_str.lstrip('-').isdigit() else 0
except:
continue
entry = {'bonus_score': bonus_score, 'grades': {}}
for ci, gname in grade_cols:
if ci < len(row):
val = row[ci].strip()
if val and val not in ['—', '-', '', '------']:
entry['grades'][gname] = parse_range(val)
if entry['grades']:
table_info['data'].append(entry)
else:
if len(row) < 3:
continue
level_name = row[0].strip()
score_str = row[1].strip()
try:
score_val = int(score_str) if score_str.isdigit() else 0
except:
continue
entry = {'level': level_name, 'score': score_val, 'grades': {}}
for ci, gname in grade_cols:
if ci < len(row):
val = row[ci].strip()
if val and val not in ['—', '-', '', '------']:
entry['grades'][gname] = parse_range(val)
if entry['grades']:
table_info['data'].append(entry)
if table_info['data']:
if is_bonus:
result['bonus_tables'].append(table_info)
else:
result['scoring_tables'].append(table_info)
return result
def print_summary(data):
m = data['metadata']
print(f"总Word表格: {m['total_tables']}")
print(f"标准评分表: {len(data['scoring_tables'])} 个")
print(f"加分评分表: {len(data['bonus_tables'])} 个")
print(f"登记卡/附表: {len(data['registration_tables'])} 个")
wt = data['weight_table']
print(f"\n权重表 ({len(wt)}组):")
for obj in sorted(wt.keys()):
items = ', '.join(f"{k}={v}%" for k, v in sorted(wt[obj].items()))
print(f" {obj}: {items}")
print(f"\n标准评分表:")
for t in data['scoring_tables']:
gn = t['grade_names']
gs = ', '.join(gn[:3])
if len(gn) > 3:
gs += f"...({len(gn)}个年级)"
levels = sorted(set(e['level'] for e in t['data']))
ti = t['table_index']
rc = len(t['data'])
print(f" [表{ti}] {rc}行x{len(gn)}年级 等级={levels} 年级={gs}")
print(f"\n加分评分表:")
for t in data['bonus_tables']:
gn = t['grade_names']
gs = ', '.join(gn[:3])
if len(gn) > 3:
gs += f"...({len(gn)}个年级)"
ti = t['table_index']
rc = len(t['data'])
print(f" [表{ti}] {rc}行 年级={gs}")
def output_json(data):
path = os.path.join(BASE, '02_加工数据/评分标准结构化数据.json')
with open(path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
size = os.path.getsize(path)
print(f"\nJSON输出: {path} ({size/1024:.0f}KB)")
return path
if __name__ == '__main__':
data = extract_all()
print_summary(data)
output_json(data)