管理端:基于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")