中药大数据(四):数据预处理+管理端的功能实现
管理端:基于vue+springboot+mysql 实现,使用echarts开发可视化,elementui实现界面
爬虫:基于python最主流的爬虫框架scrapy开发
知识图谱:基于最主流的 neo4j图数据库实现
数据爬取功能:基于scrapy爬虫进行中药药材数据和药方数据的爬取
爬取流程图:
数据预处理:从药材数据中提取药材的产地信息
从药材和药方数据中提取知识图谱信息并且构建到neo4j数据库中
系统的图谱构建由于时间比较长,我们加上了进度条日志,可以方便用户在导入数据的时候去预估时间:
图谱信息(由于前端显示限制,只展示冰山一角):
提供主页功能:管理员可以直观查看系统数据情况、用户登录的信息、3D词云
用户信息管理:可以进行用户增删改查的操作
中药材信息查询:用户可以点击系统名称进行模糊查询,或通过搜索框自主输入想要查询的信息进行中药材查询,另外支持增删改:
中药的方剂管理,支持增删改查:
中药材资讯管理:后台可以进行咨询管理。
中药材产地可视化:内含全国省份的中药材种类分布地图,这个数据是从scrapy爬虫爬取到的数据进行提取之后使用echarts可视化进行提取的
比如我们输入了青酒缸,在中国地图上金色的点位展示了产地的信息
用户可以向后台管理员发送中药药材和药方的纠错申请,管理员可以进行处理
评论管理
用户的登录和退出功能
数据预处理代码:
def input_habitat_place():
# 读取 Excel 文件
df = pd.read_excel('zhongyao_data.xlsx')
# 将 NaN 替换为空字符串
df = df.fillna('')
# 定义中国省级单位的列表,用于匹配
provinces = [
'北京', '天津', '上海', '重庆', '河北', '山西', '内蒙古', '辽宁', '吉林', '黑龙江',
'江苏', '浙江', '安徽', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东',
'广西', '海南', '四川', '贵州', '云南', '西藏', '陕西', '甘肃', '青海', '宁夏', '新疆',
'香港', '澳门', '台湾'
]
try:
# 获取数据库连接
with cnn.connect() as connection:
# 开启事务
with connection.begin() as transaction:
# 遍历 DataFrame 中的每一行,插入到数据库中
for index, row in df.iterrows():
title = row['title']
habitat = row['habitat']
# 匹配 habitat 字段中的省份
matched_provinces = [province for province in provinces if province in habitat]
# 如果找到匹配的省份,插入到数据库中
for province in matched_provinces:
sql = text("""
INSERT INTO tb_map (keyword, city, amount, deleted)
VALUES (:keyword, :city, :amount, :deleted)
""")
values = {
'keyword': title,
'city': province,
'amount': 0,
'deleted': 0
}
connection.execute(sql, values)
print(f"已处理: {title},匹配到的省份: {matched_provinces}")
# 提交事务
transaction.commit()
finally:
# 关闭数据库连接引擎
cnn.dispose()
print("数据导入成功!")
生成图谱代码:
# 创建药方和药材的知识图谱,确保节点和关系不会重复
for index, row in df_prescriptions.iterrows():
# 创建药方节点(防止重复)
prescription_node = Node("Prescription", name=row['title'],
prescription=row['prescription'],
making=row['making'],
functional_indications=row['functional_indications'],
usage=row['usage'],
excerpt=row['excerpt'],
care=row['care'])
graph.merge(prescription_node, "Prescription", "name") # 防止重复创建方剂节点
# 分割 fangji 中的药材名称
medicines = row['fangji'].split(',') if row['fangji'] else []
for medicine in medicines:
medicine = medicine.strip() # 去除药材名称前后的空格
# 从 tb_cmedicine 数据中获取该药材的详细信息
if medicine in cmedicine_dict:
med_info = cmedicine_dict[medicine]
# 创建药材节点(防止重复)
medicine_node = Node("Medicine", name=medicine,
pinyin=med_info.get('pinyin'),
alias=med_info.get('alias'),
source=med_info.get('source'),
english_name=med_info.get('english_name'),
habitat=med_info.get('habitat'),
flavor=med_info.get('flavor'),
functional_indications=med_info.get('functional_indications'),
usage=med_info.get('usage'),
excerpt=med_info.get('excerpt'),
provenance=med_info.get('provenance'),
shape_properties=med_info.get('shape_properties'),
attribution=med_info.get('attribution'),
prototype=med_info.get('prototype'),
discuss=med_info.get('discuss'),
chemical_composition=med_info.get('chemical_composition'))
graph.merge(medicine_node, "Medicine", "name") # 防止重复创建药材节点
# 创建 Prescription -> Medicine 关系(防止重复)
relationship = Relationship(prescription_node, "所用药材", medicine_node)
graph.merge(relationship, "Prescription", "name")
# 提取古籍书名号《》中的内容并创建古籍节点(药材的摘录,防止重复)
book_title = extract_book_title(med_info.get('excerpt', ''))
if book_title:
# 创建古籍节点(防止重复)
book_node = Node("Book", name=book_title)
graph.merge(book_node, "Book", "name")
# 创建 Book -> Medicine 的 "收录药材" 关系(防止重复)
recorded_relationship_medicine = Relationship(book_node, "收录药材", medicine_node)
graph.merge(recorded_relationship_medicine, "Book", "name")
# 创建 "药材归经" 关系(防止重复)
attributions = med_info.get('attribution', '').split(';') if med_info.get('attribution') else []
for attribution in attributions:
attribution = attribution.strip()
if attribution:
# 创建归经节点(防止重复)
attribution_node = Node("Attribution", name=attribution)
graph.merge(attribution_node, "Attribution", "name")
# 创建 Medicine -> Attribution 的 "药材归经" 关系(防止重复)
attribution_relationship = Relationship(medicine_node, "药材归经", attribution_node)
graph.merge(attribution_relationship, "Medicine", "name")
# 提取古籍书名号《》中的内容并创建古籍节点(方剂的摘录,防止重复)
book_title = extract_book_title(row['excerpt'])
if book_title:
# 创建古籍节点(防止重复)
book_node = Node("Book", name=book_title)
graph.merge(book_node, "Book", "name")
# 创建 Book -> Prescription 的 "收录方剂" 关系(防止重复)
recorded_relationship_prescription = Relationship(book_node, "收录方剂", prescription_node)
graph.merge(recorded_relationship_prescription, "Book", "name")