简介:这是一套面向计算机专业学生与Web开发初学者的毕业设计级项目源码,基于Python与Django框架实现专家信息管理与抽取系统,覆盖信息录入、查询、修改、删除及从非结构化文本中自动提取专家资料等核心场景,适合作为课程设计、毕设参考或Django入门实战案例。压缩包共68个文件,约180KB,以23个py源码文件为主体,辅以14个html模板、7个js脚本、3个css样式及sqlite3数据库、docx说明文档等,完整呈现模型、视图、模板三层结构与信息抽取模块的实现思路。目前已有246人学习下载。读者可从中获取可直接运行的Django工程骨架、数据库表设计与ORM用法、用户认证与权限控制示例,以及正则与NLP库结合的信息抽取代码,便于快速理解Web项目开发流程并迁移到自己的课题中。
1. 从一份 Django 毕设包说起:专家信息抽取到底难在哪
如果你正在找计算机方向的毕业设计,或者需要一套能跑通「数据录入—清洗—抽取—展示」全链路的 Django 项目,这个《专家信息管理与抽取系统》的源码包值得先看一眼。它解决的不是「做个增删改查」这种练手题,而是把专家信息这种半结构化文本,通过规则和字段映射抽成结构化数据,再落库管理。适合两类人:一是需要毕设底稿、想在此基础上改功能的学生;二是刚接触 Django,想找一个带真实业务逻辑(而不是只有博客和商城)的项目来练手的人。我拆过不少毕设包,大部分是「能跑但没灵魂」,这套的抽取模块算是有点东西,下面按「怎么装、怎么跑、怎么改、坑在哪」的顺序讲透。
2. 环境搭建与项目启动:从 python 安装到 django 创建 app
2.1 依赖版本与虚拟环境隔离
拿到源码包第一件事不是急着pip install,而是先看requirements.txt。这类毕设包常见的坑是 Django 版本和 Python 版本对不上,比如代码里用了django.urls.re_path,但你本地装的是 Django 4.x 以上,某些写法会直接报ImportError。我一般会先建虚拟环境,把版本锁死。
# 创建虚拟环境,python3.8 是这类老毕设包比较稳的选择 python3.8 -m venv venv # 激活环境,Windows 用 venv\Scripts\activate source venv/bin/activate # 升级 pip,避免装包时出现依赖解析失败 pip install --upgrade pip # 安装依赖,建议逐行看 requirements.txt 再执行 pip install -r requirements.txt逻辑说明:虚拟环境的作用是把项目依赖和你系统里的 Python 包隔开,避免「装了这个项目,别的项目跑不起来」。参数上,python3.8不是随便选的,Django 2.2 到 3.2 这段区间的项目对 3.8 兼容性最好,如果你系统只有 3.10 以上,mysqlclient这类包编译时容易翻车。requirements.txt里通常会有Django、mysqlclient或pymysql、requests、jieba(分词用)这几个核心包,版本号如果写的是==就严格照装,写>=的可以适当放宽。
2.2 数据库配置与迁移命令
专家信息管理系统一般用 MySQL,因为要存结构化的专家字段和抽取结果。打开settings.py,找到DATABASES配置段,把库名、用户、密码改成你本地的。
# settings.py 数据库配置片段 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'expert_db', # 提前在 MySQL 里建好这个库 'USER': 'root', 'PASSWORD': 'your_password', 'HOST': '127.0.0.1', 'PORT': '3306', 'OPTIONS': { 'charset': 'utf8mb4', # 必须 utf8mb4,否则中文专家名会乱码 }, } }改完配置后执行迁移。这里有个高频翻车点:如果项目用的是pymysql而不是mysqlclient,需要在__init__.py里加两行伪装代码,否则 Django 启动时会报Error loading MySQLdb module。
# 项目根目录的 __init__.py import pymysql pymysql.install_as_MySQLdb()然后跑迁移命令:
# 生成迁移文件,如果 migrations 目录已存在可跳过 python manage.py makemigrations # 执行迁移,建表 python manage.py migrate # 创建后台管理员账号 python manage.py createsuperuser # 启动开发服务器 python manage.py runserver逻辑说明:makemigrations是根据models.py里的模型类生成建表语句,migrate才是真正往数据库里执行。很多新手直接跑migrate发现没建表,就是因为漏了第一步。createsuperuser创建的账号用来登录 Django 自带的 admin 后台,方便你直接看数据表里的专家记录。启动后访问127.0.0.1:8000/admin能进后台,说明环境通了。
2.3 创建 app 与路由挂载
如果这个包是完整项目,app 一般已经建好了(比如叫expert或management)。但如果你要在此基础上加功能,得知道怎么新建 app 并挂路由。
# 新建一个 app,名字按业务起,比如 extraction python manage.py startapp extraction建完后在settings.py的INSTALLED_APPS里注册,然后在项目主urls.py里用include挂上子路由。这一步是 Django 项目实战新手最容易漏的,漏了就会出现「页面 404 但代码明明写了」的玄学问题。常见做法是每个 app 下建一个urls.py,主路由只负责分发,这样后期加模块不会把主路由写成一锅粥。
3. 专家信息抽取模块:规则、字段映射与入库逻辑
3.1 抽取流程拆解:从原始文本到结构化字段
这个系统的核心价值在「抽取」两个字。专家信息通常来源是网页简介、申报表、论文作者页,格式不统一。项目里一般会走这么一条链路:原始文本 → 分句/分词 → 关键词匹配 → 字段填充 → 人工校验 → 入库。我拆包时重点看的是extraction或utils目录下的抽取脚本,那里藏着真正的业务逻辑。
常见的实现方式有两种:一种是纯正则,适合格式固定的文本(比如「姓名:张三,单位:XX大学」);另一种是关键词 + 规则表,比如维护一个职称关键词列表,命中「教授」「副教授」「研究员」就归到职称字段。这套包大概率是后者,因为纯正则应付不了专家信息的多样性。
# 抽取核心逻辑示意,实际代码以包内为准 import re # 职称关键词表,可扩展 TITLE_KEYWORDS = ['教授', '副教授', '研究员', '副研究员', '高级工程师', '讲师'] def extract_title(text): """从文本中抽取职称字段""" for kw in TITLE_KEYWORDS: if kw in text: return kw return '未知' def extract_email(text): """用正则抽取邮箱""" pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' match = re.search(pattern, text) return match.group(0) if match else '' def extract_expert_info(raw_text): """组装抽取结果""" return { 'title': extract_title(raw_text), 'email': extract_email(raw_text), # 其他字段按同样思路补 }逻辑说明:extract_title用的是「关键词命中即返回」,简单但有效,缺点是如果文本里同时出现「教授」和「副教授」,会优先命中「教授」,因为列表顺序在前。想更准就得按长度倒序匹配,或者用分词后词性标注。extract_email的正则是通用写法,参数上{2,}表示顶级域名至少两位,能过滤掉一些明显错误的匹配。extract_expert_info是入口函数,实际项目里会把它挂到视图或 Celery 任务里,批量处理上传的文本。
3.2 字段映射与模型设计
抽取出来的字典要落库,就得有对应的 Django 模型。看models.py里专家表的设计,重点看字段类型和长度限制。
# models.py 专家信息模型示意 from django.db import models class Expert(models.Model): name = models.CharField(max_length=50, verbose_name='姓名') title = models.CharField(max_length=50, blank=True, verbose_name='职称') email = models.EmailField(blank=True, verbose_name='邮箱') organization = models.CharField(max_length=200, blank=True, verbose_name='单位') research_field = models.TextField(blank=True, verbose_name='研究方向') raw_text = models.TextField(blank=True, verbose_name='原始文本') created_at = models.DateTimeField(auto_now_add=True) class Meta: db_table = 'expert_info' verbose_name = '专家信息' def __str__(self): return self.name逻辑说明:raw_text字段很关键,它保留了抽取前的原文,方便你回溯「这个职称到底是从哪句话抽出来的」。blank=True表示表单可以为空,但数据库层面不一定允许 NULL,具体看null参数。db_table手动指定表名,避免 Django 默认生成的app名_模型名跟你预期不一致。EmailField自带格式校验,比CharField更适合存邮箱。如果项目里还有「抽取记录表」或「审核状态表」,说明它考虑了人工复核环节,这种设计在毕设里算加分项。
3.3 批量导入与抽取触发
单个录入效率太低,实际场景都是批量。项目里一般会有一个上传 Excel 或 txt 的入口,解析后逐条调抽取函数。
# 批量导入视图逻辑示意 import pandas as pd from .models import Expert from .utils import extract_expert_info def batch_import(file_path): """读取 Excel 并批量抽取入库""" df = pd.read_excel(file_path) success, fail = 0, 0 for _, row in df.iterrows(): raw = str(row.get('简介', '')) if not raw: fail += 1 continue info = extract_expert_info(raw) Expert.objects.create( name=row.get('姓名', ''), title=info['title'], email=info['email'], raw_text=raw, ) success += 1 return success, fail逻辑说明:pd.read_excel依赖openpyxl,如果报Missing optional dependency,装一下就行。row.get('简介', '')用get而不是row['简介'],是为了防止列名不存在时直接抛异常。Expert.objects.create每次一条,数据量大时会慢,常见优化是攒一批用bulk_create。success和fail计数返回给前端,让用户知道导入了多少、失败多少,这个反馈在毕设答辩时很实用。
4. 避坑与排查:那些让我熬夜的报错
4.1 迁移时报错 Table already exists
现象:执行python manage.py migrate时提示某张表已存在,迁移中断。原因通常是之前手动建过表,或者迁移记录和实际表结构不一致。解决:先python manage.py showmigrations看哪些迁移没打勾,如果是空库可以直接删表重来;如果已有数据,用migrate --fake把迁移记录标记为已执行,但前提是你确认表结构对得上。我一般会在开发阶段直接 drop 库重建,省得纠结。
4.2 中文乱码与编码问题
现象:后台录入的专家姓名显示成问号或乱码。原因多半是数据库字符集不是utf8mb4,或者连接配置里没指定 charset。解决:建库时用CREATE DATABASE expert_db CHARACTER SET utf8mb4;,settings.py的OPTIONS里加'charset': 'utf8mb4'。如果已经建了库,用ALTER DATABASE改字符集,但已有数据可能救不回来,得重新导。
4.3 抽取结果为空或字段错位
现象:批量导入后,职称字段全是「未知」,或者邮箱抽到了别人的。原因一般是关键词表覆盖不全,或者正则匹配到了文本里第一个邮箱而不是目标专家的。解决:先把raw_text打出来看原文长什么样,再调关键词表和正则。如果是多专家混在一段文本里,就得先做分句或分段,不能整段丢给抽取函数。这个坑我在多个项目里都踩过,血泪经验是:抽取前先做数据清洗,比调抽取算法本身更重要。
4.4 静态文件 404 与 DEBUG 模式
现象:页面样式全丢,控制台报静态文件 404。原因:Django 开发模式下静态文件需要配置STATIC_URL和STATICFILES_DIRS,如果DEBUG = False还得配STATIC_ROOT并用collectstatic。解决:开发阶段保持DEBUG = True,确认INSTALLED_APPS里有django.contrib.staticfiles,模板里用{% static 'xxx.css' %}引用。上线前再切DEBUG = False并跑收集命令,别提前关,否则排查起来很痛苦。
4.5 端口占用与 runserver 启动失败
现象:python manage.py runserver报Error: That port is already in use。原因:8000 端口被别的进程占了,或者上次的 runserver 没关干净。解决:换端口python manage.py runserver 8001,或者用lsof -i:8000(Linux/Mac)找到进程 kill 掉。Windows 上用netstat -ano | findstr 8000查 PID,再任务管理器结束。这个不算大坑,但新手容易卡住。
5. 二次开发与抽取准确率提升技巧
如果你拿这套包做毕设,光跑通不够,答辩老师大概率会问「抽取准确率怎么保证」。我的做法是加一层「规则 + 人工校验」的闭环:抽取结果先落一张临时表,标记status=pending,后台提供一个审核页面,人工确认后才写入正式专家表。这样既展示了抽取能力,又体现了对数据质量的把控。
具体实现上,可以在Expert模型加一个status字段,默认pending,审核通过改confirmed。列表页按状态筛选,审核页用 Django 的ModelForm快速搭。另一个提准确率的技巧是把关键词表做成可配置的,存到数据库或配置文件里,而不是硬编码在 Python 里,这样改词不用动代码。
# 可配置关键词表的简单实现 class KeywordRule(models.Model): field_name = models.CharField(max_length=50) # 对应抽取字段,如 title keyword = models.CharField(max_length=100) # 关键词,如 教授 priority = models.IntegerField(default=0) # 优先级,数字大的先匹配 class Meta: db_table = 'keyword_rule'抽取时从数据库读规则,按priority倒序匹配,命中即停。这样「副教授」和「教授」的优先级就能手动调,不用改代码。验证方法也简单:准备 20 条测试文本,人工标好期望结果,跑一遍抽取,统计字段命中率。我一般会把这个统计脚本单独放一个tests目录,答辩时直接展示准确率数字,比空口说「效果不错」有说服力。
从那以后我每次拿到这类毕设包,都强制先跑一遍最小闭环:建库、迁移、建超管、录一条数据、看抽取结果,再动任何代码。希望帮到你。
本文还有配套的精品资源,点击获取