做医疗相关数据分析或者公共卫生研究的朋友应该都遇到过数据难题想做疾病趋势分析却不知道哪些数据能合法采集要么找不到公开数据源要么怕一不小心触碰患者隐私红线。网上很多教程一上来就教爬医院系统殊不知很多操作已经踩了合规的红线甚至涉嫌违法。前段时间帮朋友做一组公开疾病数据的趋势分析从数据源筛选、合规采集、文本清洗结构化到最后的趋势分析与可视化完整走了一遍流程。全程只采集完全公开的匿名聚合数据不碰任何个人隐私信息最终出来的分析结果完全能满足常规研究需求。今天就把完整的实现思路、核心代码和合规注意事项全部分享出来全程合法合规新手也能照着复现。一、先划红线医疗数据采集的合规边界与数据源选择做医疗数据采集合规永远是第一位的比技术实现重要一百倍。一旦触碰了个人隐私数据后果不堪设想。先把不能碰的红线划清楚绝对不能爬取医院内部系统、非公开的电子病历系统哪怕有可访问账号也不行绝对不能采集包含患者姓名、身份证号、联系方式、具体就诊记录等可识别个人身份的信息不能突破网站的授权机制爬取需要权限才能查看的非公开数据不能对采集到的数据进行二次传播、商用要严格遵守数据使用协议合规可采集的公开医疗数据不是所有医疗数据都不能碰以下几类公开数据是可以合规采集的各级卫健委、疾控局官方发布的公开疾病监测数据、统计报表公立医疗机构公开的年度医疗质量报告、疾病科普与汇总数据公开医学期刊、学术平台发布的匿名化病例汇总数据国家公共卫生科学数据中心等官方平台开放的共享数据集法定公开的传染病疫情通报、公共卫生事件数据这些数据都是经过匿名化、聚合处理的公开信息采集时遵守网站robots协议和使用规定控制请求频率就完全合规。技术选型为什么选这套轻量方案而不是更复杂的技术栈采集层官方公开站点大多是传统服务端渲染页面没有复杂的前端反爬requestsBeautifulSoup完全够用轻量高效处理层医疗文本结构化用正则自定义医疗词典配合pandas做数据处理比通用大模型更可控准确率也能满足需求分析层pandas做统计聚合、时间序列分析搭配matplotlib做可视化本地就能跑无需额外部署合规性全程只处理公开聚合数据不涉及任何个人隐私识别整体处理流程二、分步实操从采集到分析的完整实现2.1 公开数据采集以官方疾病监测数据为例这里以某地方卫健委公开的月度疾病监测数据为例这类数据通常以表格形式分页展示没有复杂反爬重点是控制频率规范采集。核心思路先获取列表页解析每条数据的详情链接再逐个采集详情页的内容最后汇总成结构化表。注意不要开高并发单线程加间隔避免给服务器造成压力。核心代码片段import requests from bs4 import BeautifulSoup import pandas as pd import time session requests.Session() session.headers.update({ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36, Referer: [http://wjw.xxx.gov.cn/disease/list/](http://wjw.xxx.gov.cn/disease/list/) }) disease_list [] total_page 12 # 公开数据总页数 for page in range(1, total_page 1): url f[http://wjw.xxx.gov.cn/disease/list/index_{page}.html](http://wjw.xxx.gov.cn/disease/list/index_{page}.html) resp session.get(url, timeout10) resp.encoding utf-8 soup BeautifulSoup(resp.text, html.parser) # 解析列表中的每条数据 items soup.find_all(div, class_list-item) for item in items: title item.find(a).text.strip() detail_url item.find(a)[href] publish_date item.find(span, class_date).text.strip() # 只采集月度疾病监测通报 if 月度疾病监测 in title: disease_list.append({ title: title, detail_url: detail_url, publish_date: publish_date }) print(f第{page}页采集完成当前累计{len(disease_list)}条) time.sleep(1.5) # 控制请求频率避免给服务器造成压力 # 采集详情页数据 detail_data [] for idx, item in enumerate(disease_list): resp session.get(item[detail_url], timeout10) resp.encoding utf-8 soup BeautifulSoup(resp.text, html.parser) content soup.find(div, class_content).text.strip() detail_data.append({ month: item[title], publish_date: item[publish_date], content: content }) time.sleep(1) if idx % 10 0: print(f详情页采集进度{idx1}/{len(disease_list)}) # 保存原始数据 df pd.DataFrame(detail_data) df.to_csv(disease_raw.csv, indexFalse, encodingutf-8-sig) print(f采集完成共获取{len(df)}份月度监测数据)几个关键的合规细节严格控制请求频率每页间隔1秒以上绝不使用多并发轰炸官方站点只采集公开可访问的页面不尝试绕过登录、不破解权限采集的数据仅用于研究分析不二次传播、不商用2.2 医疗文本清洗与实体结构化提取采集下来的原始数据大多是自然语言文本比如“本月报告甲类传染病2例乙类传染病1256例其中病毒性肝炎320例肺结核280例…”需要从中提取出疾病名称、病例数、时间这些结构化字段。通用的NLP模型对医疗术语的识别准确率很低这里不用复杂模型用正则匹配自定义疾病词典的方案准确率高可控性强完全能处理标准化的公开报告。第一步先构建自定义疾病词典把常见的传染病、慢性病名称整理进去# 自定义疾病词典示例可根据需求扩展 DISEASE_DICT [ 病毒性肝炎, 肺结核, 梅毒, 淋病, 细菌性痢疾, 流行性感冒, 手足口病, 水痘, 麻疹, 风疹, 高血压, 糖尿病, 冠心病, 脑梗死, 恶性肿瘤 ]然后写提取函数从文本中匹配疾病名称和对应的病例数import re import pandas as pd df pd.read_csv(disease_raw.csv) def extract_disease_data(text, month): 从监测文本中提取疾病名称和病例数 results [] # 预处理去掉多余空格和换行 text re.sub(r\s, , text) for disease in DISEASE_DICT: # 匹配模式疾病名称 数字 例 pattern re.compile(f{disease}[^0-9]*(\d)[^0-9]*例) match pattern.search(text) if match: count int(match.group(1)) results.append({ month: month, disease: disease, case_count: count }) return results # 批量提取所有月份的数据 all_data [] for _, row in df.iterrows(): month_data extract_disease_data(row[content], row[month]) all_data.extend(month_data) # 转成DataFrame structured_df pd.DataFrame(all_data) # 数据校验剔除异常值 structured_df structured_df[structured_df[case_count] 0] structured_df structured_df[structured_df[case_count] 100000] # 合理范围校验 structured_df.to_csv(disease_structured.csv, indexFalse, encodingutf-8-sig) print(f结构化完成共提取{len(structured_df)}条疾病数据)补充说明真实场景的文本格式会更多样需要根据实际报告的格式调整正则规则可以加入同义词映射比如“乙肝”对应“病毒性肝炎乙型”提高召回率提取完一定要做数据校验剔除明显不符合常理的异常值避免影响分析结果2.3 疾病趋势统计分析与可视化数据结构化之后就可以做多维度的趋势分析了。常规的分析维度包括时间维度的发病趋势、疾病类型的占比分布、季节性特征分析、同比环比变化等。这里做两个最常用的分析月度发病趋势变化、疾病类型占比分析。核心代码片段import pandas as pd import matplotlib.pyplot as plt import matplotlib # 设置中文显示 matplotlib.rcParams[font.sans-serif] [SimHei] matplotlib.rcParams[axes.unicode_minus] False df pd.read_csv(disease_structured.csv) # 1. 月度总发病数趋势 monthly_total df.groupby(month)[case_count].sum().reset_index() plt.figure(figsize(12, 6)) plt.plot(monthly_total[month], monthly_total[case_count], markero, linewidth2, color#1f77b4) plt.title(月度法定传染病发病数趋势, fontsize14) plt.xlabel(月份, fontsize12) plt.ylabel(发病数例, fontsize12) plt.xticks(rotation45) plt.grid(alpha0.3) plt.tight_layout() plt.savefig(monthly_trend.png, dpi300) plt.close() # 2. 疾病类型占比全年汇总 disease_total df.groupby(disease)[case_count].sum().reset_index() disease_total disease_total.sort_values(case_count, ascendingFalse).head(10) plt.figure(figsize(10, 6)) plt.bar(disease_total[disease], disease_total[case_count], color#2ca02c) plt.title(全年各类疾病发病数TOP10, fontsize14) plt.xlabel(疾病类型, fontsize12) plt.ylabel(发病数例, fontsize12) plt.xticks(rotation45) plt.tight_layout() plt.savefig(disease_rank.png, dpi300) plt.close() # 3. 计算同比环比 monthly_total[month_num] range(1, len(monthly_total)1) monthly_total[mom] monthly_total[case_count].pct_change() * 100 # 环比 monthly_total[yoy] monthly_total[case_count].pct_change(12) * 100 # 同比 print(月度发病数同比环比) print(monthly_total[[month, case_count, mom, yoy]].tail(6))这样就能得到直观的趋势图表和统计数据满足常规的公共卫生研究、数据分析需求。如果需要更深入的分析还可以加入地区维度、人群维度的交叉分析。三、踩坑实录医疗数据采集分析最容易踩的5个坑这套流程跑下来踩了不少和医疗数据特性相关的坑很多都是做普通数据采集碰不到的整理出来帮大家避坑。3.1 合规红线坑别拿隐私数据开玩笑这是最重要的一条。很多人觉得反正数据在网页上就能看到爬下来也没事。实际上只要包含可识别的个人信息哪怕是公开在医院网站上的批量采集也可能涉嫌侵犯个人信息。记住一个原则只采集聚合的、匿名的、统计类的数据不碰任何具体的个人就诊记录。哪怕是公开的病例也要确认是完全匿名化、无法定位到个人的。3.2 数据口径不一致坑直接对比等于白分析不同地区、不同年份的疾病统计口径很可能不一样比如有的地方把疑似病例算进去有的只算确诊有的月份调整了统计范围。如果不看说明直接拉过来就对比分析出来的趋势完全是错的。采集的时候一定要把每个报告的统计说明、口径注释一起保存下来分析前先对齐口径不一致的数据不能放在一起比。3.3 医疗实体识别坑通用NLP根本不好用最开始图省事用通用的分词工具做实体提取结果疾病名称识别错漏百出把“病毒性肝炎”拆成“病毒”“性”“肝炎”根本没法用。医疗领域有大量专业术语通用模型没有经过专项训练准确率极低。不要迷信大模型小批量标准化的数据用自定义词典正则的方案准确率更高还更可控。3.4 数据失真坑公开数据也会“改数”官方公开的监测数据有时候会有修正比如本月发布的数据下个月可能会订正。如果采集完就不管了后面数据更新了你也不知道分析结果就会有偏差。建议定期增量更新数据同时保留历史版本标注数据的采集时间和发布版本出现差异的时候可以追溯。3.5 采集频率坑别给官方服务器添乱医疗相关的官方站点服务器资源大多优先保障业务使用尤其是疾控、卫健委的网站遇到公共卫生事件的时候访问量本来就大。这时候开多线程高并发去爬不仅不道德还很容易被封IP甚至可能承担相应责任。单线程1秒以上间隔是基本操作数据量不大的话慢一点也没关系合规稳定最重要。四、总结医疗数据采集分析技术从来都不是最大的难点合规才是。很多人一上来就研究怎么爬医院系统、怎么搞病历数据方向从一开始就错了。实际上公开的官方统计数据、学术共享数据已经足够满足绝大多数研究和学习需求。
企业数字化 ERP 产品动态
相关推荐
GSEA结果解读与完整分析流程:从基因排序到上下调通路识别 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 7:49:52
分治法的递归实现 分治法的递归实现
一. 分治思想
分治法核心:分、治、合
分:将大问题拆分为多个结构相同的子问题治:递归求解子问题,子问题足够小时直接返回(递归出口)合:合并子问题的解,得到原问题结… · 2026/9/24 7:49:33
汇川IS620伺服调试实战:InoServoShop连接、参数监控与备份全攻略 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 7:49:21
SWIR051AU短波红外相机:从InGaAs原理到工业检测实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 8:25:15
LTspice第三方SPICE模型集成全流程指南 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 8:25:02
芯片IP选型避坑指南:架构适配、工艺兼容与验证完备性实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 8:24:56
Vega 平行坐标图实战:多维汽车数据的 axes-offset 折线布局规范全解析 数据可视化 【免费下载链接】vega A visualization grammar. 项目地址: https://gitcode.com/gh_mirrors/ve/vega 点击查看 免费下载 平行坐标(Parallel Coordinates)是一种用于多维数据可视化的经典图表:每个维度占据一条平行的… · 2026/9/24 8:24:31
RLHF、InstructGPT 与 DPO:大模型对齐训练全面解析 本文系统讲解大模型对齐训练的核心方法:RLHF(基于人类反馈的强化学习)、InstructGPT 的三步对齐流程,以及 DPO(直接偏好优化)。从原理、步骤、优缺点到实践细节,一篇讲透。一、什么是 RLHF&… · 2026/9/24 8:24:25
激光二极管恒流驱动设计核心:精度、热管理与环路稳定性 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/24 8:24:19
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44