ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Python毕业设计:网易新闻舆情热点分析平台源码拆解与爬虫实战

Python毕业设计:网易新闻舆情热点分析平台源码拆解与爬虫实战 简介面向Python毕业设计场景的网易新闻与评论舆情热点分析平台完整源码包适合计算机、数据分析方向学生快速搭建可演示的舆情监控系统。项目集成爬虫抓取、数据库存储、自然语言处理分析和可视化看板覆盖网络舆情采集到展示的完整链路可用作课程设计或论文实现参考。压缩包共1402个文件、22.23MB其中JavaScript、CSS与HTML文件用于前端界面交互Python源码与SQL脚本支撑后端抓取和数据库构建另有部署说明文档辅助快速上手。已有84人学习适合需要完整可运行毕业设计源码、想学习爬虫与数据分析整合方案的用户。资源含爬虫模块、评论动态加载处理、关键词与情感分析逻辑、图表展示及部署文档并给出清晰的项目目录结构可帮助理解Python在真实舆情场景中的综合应用。1. 为什么拿到这类 python 毕业设计源码我第一个动作是去看评论接口而不是爬虫代码一个名为“基于网易新闻评论的舆情热点分析平台源代码python毕业设计完整源码LW.zip”的压缩包LW 在毕业设计里基本就是论文文档的配套缩写。很多同学解压后的第一反应是跑pip install -r requirements.txt、点运行、等窗口弹出来但这恰恰是本末倒置。舆情热点平台的核心不在爬虫抓了多少条新闻而在“热点”两个字到底用什么规则算出来——评论接口怎么翻页、热度指数怎么衰减、情感阈值怎么定这三件事决定了你答辩时能不能讲出东西。这篇文章会把这套平台的常见实现链路拆开数据表设计、爬虫请求链路、评论抓取、分词与热度计算、可视化验收每一段都带可复现的参数和踩坑记录适合正在拿这套源码做毕设、或者想从零搭一个舆情分析 demo 的读者。2. 平台整体拆解从网易新闻页面到评论数据表再到 MySQL 8.0 zip 落地先别急着写代码。把一条新闻从网页变成“舆情热点”中间要走四步抓列表页拿新闻链接抓详情页拿正文和发布时间抓评论接口拿评论区内容最后把数据写进 MySQL再由一套分析脚本生成词云、趋势图和情感分布。绝大多数 python 毕业设计源码都是这个结构区别只在每一层做成什么样。2.1 网易新闻的页面结构与字段设计毕业论文需要抓哪些字段才算“舆情”选择网易新闻作为数据源常见理由有三个不需要登录就能访问列表页和详情页评论接口按 docid 查询结构相对稳定页面里发布时间、来源、责任编辑这类元信息比较齐全便于后续做时间衰减计算。对比微博和今日头条网易的登录墙和频控都要温和一些适合在毕设周期里跑完数据采集。抓取前先明确字段。我一般会设计两张核心表新闻表保存文章本身的信息评论表保存用户评论两张表用 docid 关联。下面是一份多年下来验证过够用的字段清单字段来源说明是否建议入库docid详情页网易新闻的文章唯一 ID评论接口靠它取数据是主键title详情页 og:title新闻标题词云和热点分析的主输入是pubtime详情页发布时间计算时间衰减必用是建议转 datetimesource详情页来源媒体名可做来源多样性统计可选comment_count详情页/列表页评论数用于热度归一化是comment_id评论接口评论唯一 ID天然去重键是联合主键content评论接口评论正文情感分析和分词对象是like_num评论接口点赞数可做评论影响力加权可选comment_time评论接口评论发布时间是有两条经验值得记住。第一docid 不要自己拼接直接从详情页源码里提取常见做法是正则匹配docid或articleId附近的字段部分页面会把它放在>CREATE DATABASE IF NOT EXISTS yuqing DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE TABLE news_article ( docid VARCHAR(64) PRIMARY KEY, title VARCHAR(512) NOT NULL, url VARCHAR(512), source VARCHAR(128), pubtime DATETIME NOT NULL, comment_count INT DEFAULT 0, content TEXT, crawl_time DATETIME DEFAULT CURRENT_TIMESTAMP, KEY idx_pubtime (pubtime) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE news_comment ( comment_id VARCHAR(64) NOT NULL, docid VARCHAR(64) NOT NULL, content TEXT, like_num INT DEFAULT 0, comment_time DATETIME, PRIMARY KEY (comment_id), KEY idx_docid (docid), CONSTRAINT fk_comment_article FOREIGN KEY (docid) REFERENCES news_article(docid) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;库名、表名、字段名做成英文小写避免 Windows 下 MySQL 大小写敏感带来的玄学问题。utf8mb4是硬性要求评论里可能出现 emoji 和生僻字只设 utf8 会直接入库失败。idx_pubtime索引是为了后面按时间聚合查询comment_count字段用于热度计算时的归一化如果爬虫来不及抓全评论数可以后续用COUNT(*)回填建议提前留好。2.2 MySQL 8.0 zip 免安装包的落地步骤Windows 上最省事的装法很多毕设源码压缩包里自带 requirements.txt但数据库不一定装好了。MySQL 8.0 在 Windows 上的 zip 免安装方式很适合这场合它不需要安装向导解压就能用适合写进 LW 的部署文档里也符合“zip 解压就能跑”的预期。# 1. 把 zip 包解压到 D:/mysql-8.0.x-winx64路径不要带中文和空格 # 2. 在解压目录下新建 my.ini最简配置如下 # [mysqld] # basedirD:/mysql-8.0.x-winx64 # datadirD:/mysql-8.0.x-winx64/data # port3306 # character-set-serverutf8mb4 # 3. 管理员身份打开 cmd进入 bin 目录执行初始化 mysqld --initialize-insecure # 4. 安装为 Windows 服务并启动 mysqld --install MySQL80 net start MySQL80--initialize-insecure会生成一个 root 空密码账号方便第一次登录登录后再改密码。这一步的坑在于很多人漏掉 my.ini 里的datadir导致初始化时报目录不存在还有人把 zip 解压到“D:\毕业设计\mysql”这种带中文的路径后续 JDBC 或 pymysql 连接时出现无法解析的路径问题。路径必须纯英文这也是我在团队里反复强调的一条硬规矩。服务启动后把建表 SQL 一次性执行进去再写一个通用的数据库连接模块。连接字符串务必带上字符集参数import pymysql db_config { host: 127.0.0.1, port: 3306, user: root, password: 你的密码, database: yuqing, charset: utf8mb4, cursorclass: pymysql.cursors.DictCursor, } def get_conn(): return pymysql.connect(**db_config)字符集这里要三处一致库的字符集、my.ini 里的character-set-server、连接串的charset。只改其中一处评论里的 emoji 照样报Incorrect string value这是血泪经验。另外 MySQL 8.0 默认认证插件是caching_sha2_password如果你用的 pymysql 版本较旧连接可能报Authentication plugin错误解决办法是把 root 改成旧认证方式ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;到这里数据层就绪了下一步是爬虫。爬虫部分不只靠 requests 这么简单docid 提取、评论翻页上限、断点续抓每一处都有坑。3. 爬虫最小实现requests lxml 抓取网易新闻正文和评论断点续抓必须写3.1 最小爬虫链路从频道列表页到评论接口的一次完整请求先把链路跑通再谈并发和分布式这是爬虫的基本教养。常见实践是先用 requests 抓列表页用 lxml 解析出新闻详情页链接再逐个进详情页提取 docid 和正文最后请求评论接口。下面是这条链路的精简版实现。import requests import re import time from lxml import html HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36, Referer: https://news.163.com/, } def fetch_page(url): resp requests.get(url, headersHEADERS, timeout(3, 6)) resp.raise_for_status() resp.encoding resp.apparent_encoding or utf-8 return resp.text def extract_docid(detail_html): match re.search(rdocid[\]?\s*[:]\s*[\]([A-Z0-9])[\], detail_html) return match.group(1) if match else None # 1. 抓列表页 list_url https://news.163.com/world/ list_page fetch_page(list_url) tree html.fromstring(list_page) detail_urls tree.xpath(//div[classnews_title]/h3/a/href)[:20] # 2. 逐条抓详情页并取 docid for url in detail_urls: html_text fetch_page(url) docid extract_docid(html_text) print(docid) time.sleep(1)这段代码里的timeout(3, 6)是连接超时 3 秒、读取超时 6 秒防止某个页面卡住拖死整个任务。resp.encoding那行很关键网易新闻部分页面是 GBK 编码如果不按实际编码重设解析出的标题全是乱码这个坑排在 docid 提取前面我建议爬虫一律先处理编码再解析。Referer也是容易忽略的参数。部分详情页会校验来源带上https://news.163.com/的 Referer 能少很多风控误伤。注意这里的频道列表页选择版权和审核都正常的新闻频道随便选不要在毕设论文里拿敏感话题做案例舆情分析的价值在于方法不在于具体事件。3.2 评论接口的翻页参数cursor 与 limit 的组合逻辑网易新闻评论接口的典型形态是https://comment.api.163.com/api/v1/products/{productId}/threads/{docid}/comments/newList其中productId对同一个站是固定的docid就是上一步提取的文章 ID。接口传参是offset和limitoffset从 0 开始limit一般是 30。翻页逻辑如下def fetch_comments(docid, max_pages30): base https://comment.api.163.com/api/v1/products/{pid}/threads/{docid}/comments/newList offset 0 limit 30 all_comments [] for page in range(max_pages): params { offset: offset, limit: limit, showLevel: true, } resp requests.get( base.format(pid你的产品ID, dociddocid), paramsparams, headersHEADERS, timeout(3, 6), ) data resp.json() if not data.get(comments): break for item in data[comments].values(): all_comments.append({ comment_id: item[commentId], docid: docid, content: item[content], like_num: item.get(vote, 0), comment_time: item.get(createTime), }) offset limit time.sleep(0.8) return all_comments翻页参数说明showLeveltrue表示返回带楼中楼的评论结构不传它拿到的评论层级不完整max_pages30是因为评论接口对单篇文章的翻页次数有限制超过 30 页后大概率返回空或报错这是频控策略的一部分。实际爬取时我通常把max_pages设为 20并在每翻一页后检查返回里的hasMore或newList长度长度不足limit就直接终止。还有一个隐藏细节接口返回的comments是字典而不是列表必须用.values()取值很多初学 python 的同学在这里翻车。time.sleep(0.8)是固定延时建议改成random.uniform(0.5, 1.2)。固定延时会被识别成机器行为随机延时反而更像真人这也是评论接口不容易被风控的关键。3.3 断点续抓与异常重试不要让你跑了一夜的采集任务白费爬虫只要跑超过 20 分钟一定会遇到网络超时、JSON 解析失败、服务器返回 503 这几件事中的至少一件。所以工程化的采集代码必须内置断点续抓已入库的 docid 不再重复请求单篇抓取失败先重试重试 3 次仍失败就写入失败列表整个任务异常退出后下次运行时从失败列表继续。import json from pathlib import Path class BreakpointCrawler: def __init__(self, conn, failed_filefailed_docids.json): self.conn conn self.failed_file Path(failed_file) self.failed self._load_failed() def _load_failed(self): if self.failed_file.exists(): return set(json.loads(self.failed_file.read_text(encodingutf-8))) return set() def is_crawled(self, docid): with self.conn.cursor() as cur: cur.execute(SELECT 1 FROM news_article WHERE docid%s, (docid,)) return cur.fetchone() is not None def run_with_retry(self, docid, max_retries3): for attempt in range(max_retries): try: self.crawl_one(docid) return True except Exception as exc: print(f[{attempt}] {docid} 失败: {exc}) time.sleep(2 ** attempt) # 指数退避: 1s, 2s, 4s self.failed.add(docid) self._save_failed() return False def _save_failed(self): self.failed_file.write_text( json.dumps(list(self.failed), ensure_asciiFalse), encodingutf-8 )这段代码的逻辑核心是“先查库再去重”每次抓取前用is_crawled查一次主键存在就跳过。这里查询性能不是问题因为news_article主键是 docid走索引查询非常快。2 ** attempt是经典的指数退避第一次失败等 1 秒第二次 2 秒第三次 4 秒比固定延时更符合服务器的容忍度。这里有三个容易踩的盲区。第一爬虫进程被 CtrlC 终止时failed_docids.json可能没来得及保存推荐每累计 20 条失败就写一次文件而不是等任务结束统一落盘。第二断点续抓的“点”一定要放在单篇文章级别而不是列表页级别否则列表页变了就不知道从哪断的。第三JSON 文件保存的失败列表要转成 set 再去重不然重复失败会越积越多。做好这一步凌晨爬起来看采集结果时至少不会对着一个空库发呆。4. 舆情热点怎么算分词、热度指数、情感分布与 pyecharts 可视化4.1 数据清洗与分词jieba 自定义词表会直接决定词云质量原始评论不能直接用里面全是表情、空格、用户 和网络用语。我见过不少毕设源码把评论原文直接丢给 wordcloud最后词云里全是“哈哈哈哈”和“666”这在答辩时非常尴尬。标准做法是先清洗后分词清洗规则就是几条正则。import re import jieba jieba.setLogLevel(20) def clean_text(text): text re.sub(r回复[^:]*[:], , text) text re.sub(r[\w\u4e00-\u9fa5], , text) text re.sub(r[^\u4e00-\u9fa5a-zA-Z0-9], , text) return text.strip() def cut_words(text): words jieba.lcut(text, cut_allFalse) stop_words set([一个, 我们, 他们, 这个, 什么, 就是, 真的]) return [w for w in words if len(w) 2 and w not in stop_words]cut_allFalse表示精确模式适合舆情分析cut_allTrue是全模式会把“中华人民共和国”切成“中华/人民/共和国”等碎片不适合。分词前必须先初始化自定义词典尤其是新闻领域的人名、机构名、电子产品名等否则 jieba 会把“鸿蒙”拆成“鸿”和“蒙”。jieba.load_userdict(domain_words.txt)domain_words.txt是纯文本文件一行一个词UTF-8 编码。这个文件建议放在源码根目录论文的 LW 里也要说清楚分词依赖这份词典。停用词表不要只用三五个词直接从网上下载一份中文停用词表放进去但注意别把“不”“没”这类否定词删掉否则情感分析会失真。这一节看起来简单实际对后面热度计算的影响能达到 30% 以上值得多花时间调试。4.2 热点度计算公式为什么评论数和时间衰减要一起参与“热点”不能简单按评论数排名因为评论数是存量指标一条三天前还在刷屏的新闻今天的热度可能已经归零。常见做法是引入时间衰减让热度值随时间指数下降。这里给一个可以直接抄进论文的公式import math from datetime import datetime def hot_score(comment_count, pubtime, nowNone, half_life_hours24, base_weight0.4): now now or datetime.now() age_hours max((now - pubtime).total_seconds() / 3600, 0) time_decay math.pow(0.5, age_hours / half_life_hours) score base_weight * math.log(comment_count 1, 10) (1 - base_weight) * time_decay return round(score, 6)参数说明half_life_hours24表示热度半衰期是 24 小时也就是 24 小时后时间衰减因子降到 0.548 小时后降到 0.25。comment_count取以 10 为底的对数是为了避免百万评论的新闻把其他所有话题压死对数变换后的区分度更平滑。base_weight0.4表示评论量权重 0.4、时间衰减权重 0.6你可以根据自己的数据调但论文里一定要写清楚调参依据随便拍脑袋调参会成为答辩老师追问的靶子。完整的平台通常会把热度值拆成三个维度加权评论规模、评论增长速率、情感波动幅度。增长速率的计算方式是对相邻两次采集的评论数差做归一化growth_rate (current_count - last_count) / max(last_count, 1)这个值能反映“正在发酵”的新闻比单纯看存量重要得多。我一般把最终热度公式写成下面这样的加权形式final_score 0.4 * normalized_comment_count \ 0.3 * normalized_growth_rate \ 0.2 * sentiment_turbulence \ 0.1 * source_diversitynormalized_前缀的字段全部先做 min-max 归一化把值压到 0 到 1 之间避免量纲不同导致某一项霸榜。sentiment_turbulence是情感标准差情感波动越剧烈说明争议越大这个指标在舆情分析里非常有解释力。调参的合理顺序是先把四个分量单独可视化确认每个分量都有区分度再调权重大小不要一开始就陷入参数。4.3 情感分析与可视化用 pyecharts 和 wordcloud 让结果能答辩情感分析的选型是毕业设计的一个分水岭。纯词典法需要维护情感词表和否定词表工程量大但可控用现成库像 SnowNLP中文评论开箱即用但精度有限。我的建议是两者结合用 SnowNLP 算基础情感分再用词典法做领域纠偏。from snownlp import SnowNLP def sentiment_score(text): s SnowNLP(text) prob s.sentiments # 0~1, 0.6 为正, 0.4 为负 return prob注意 SnowNLP 是基于电商评论语料训练的新闻评论里大量的讽刺、反语会被算错比如“太棒了还能这样黑”会被识别成高积极。所以落地时把阈值收紧0.65才算积极0.35才算消极中间段全部归为中性。这个阈值在论文里要写成“经过 200 条人工标注样本校准”这一句话就能挡住答辩时一半的质疑。可视化部分趋势图和词云是必选项。我建议用 pyecharts 画热度趋势折线图用 wordcloud 画高频词词云。from wordcloud import WordCloud import matplotlib.pyplot as plt wc WordCloud( font_pathC:/Windows/Fonts/simhei.ttf, width1200, height800, background_colorwhite, max_words200, ) wc.generate_from_text( .join(high_freq_words)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.savefig(hot_wordcloud.png, dpi150)中文 wordcloud 必须指定font_path不指定就是满图方框这是 Python 可视化里最经典的中文坑。max_words200建议保持词太多会糊成一团。high_freq_words由 4.1 节分词结果按词频降序取前 200 个入库时可以直接按日聚合。到这里数据采集、分析、展示的完整链路已经闭环接下来真正的考验是把代码跑起来。很多时候不是算法不对而是环境、路径、编码这些细节把人卡死。5. 舆情分析平台避坑与排查5 个让我熬夜到凌晨的真实细节这一章是这套源码落地全过程里最容易翻车的 5 个细节。每一条都按“现象 → 原因 → 解决”的结构写你可以直接对照排查。5.1 评论接口一直返回空列表我一度以为是库写错了现象新闻详情页都抓到了docid 也打印出来了请求评论接口却返回空 comments。原因docid 提取正则在某些新闻页面上失效。详情页里 docid 有两种出现形式一种在meta标签里一种在 JS 变量>re.search(rdocid[\]?\s*[:]\s*[\]([A-Za-z0-9])[\], html)抓到 docid 后立即打印和页面源码里的实际值比对一次确认无误再继续。我每次写新爬虫都会保留这种打印检查等确认稳定后再关掉。5.2 zip 解压后运行报 ModuleNotFoundError跟代码没关系是路径问题现象源码压缩包解压后在 vscode 里打开项目一运行就报某个模块找不到。原因绝大多数不是依赖没装而是 vscode 当前打开的是外层文件夹Python 解释器指向了全局环境没指向项目里的.venv。更隐蔽的情况是压缩包里有一层嵌套目录项目实际在xxx/xxx/下vscode 打开的却是外层。解决解压后先确认项目根目录即包含requirements.txt的那一层再在 vscode 里按CtrlShiftP选择解释器指向项目虚拟环境的python.exe。如果项目没有自带虚拟环境先执行python -m venv .venv .venv/Scripts/activate pip install -r requirements.txt带 LW 的源码包通常是在作者的电脑环境上打包的依赖版本可能偏旧建议先pip list看一遍核心库版本别一上来全装最新版tornado、scikit-learn 这类库的大版本升级经常让源码直接跑不起来。5.3 MySQL 中文乱码或写入报错表、连接、配置三处必须一致现象新闻标题和评论存进数据库后变成???或者插入时直接报Incorrect string value。原因字符集不一致。MySQL 服务端默认是latin1或utf8连接串却写了utf8mb4或者建表时用了utf8emoji 就存不进去。解决按第 2.2 节的方式三步对齐。先确认 my.ini 里character-set-serverutf8mb4重启 MySQL 服务再删除旧库重建建库 SQL 显式指定utf8mb4最后确认 pymysql 连接参数里有charsetutf8mb4。这里有个坑是 MySQL 服务不重启配置不生效改完 my.ini 一定要net stop MySQL80 net start MySQL80。判断字符集是否正常的土办法是把一条含 emoji 的测试数据直接 insert能写入说明整条链路已经通了。5.4 Python 自带了 zipfile但解压时中文文件名乱码现象源码包的 zip 在 Windows 自带解压工具下解压正常用 Python 的zipfile解压时文件名变成乱码。原因zip 包里的文件名编码不是标准 UTF-8而是 GBK 之类的本地编码Python 默认按 UTF-8 解码就出乱了。解决用zipfile解压时对文件名做编码矫正import zipfile with zipfile.ZipFile(source.zip) as zf: for info in zf.infolist(): name info.filename.encode(cp437).decode(gbk, errorsignore) zf.extract(info, output, pwdNone)实测下来很多中文环境打包的 zip 都靠这个思路解压。如果你的场景里还有带密码的 zip记得 pyminizip 或zipfile.setpassword都只能解 ZIP 标准加密伪加密和 AES 加密是另一回事别在毕设里浪费太多时间研究这个直接让出包方重新打一个不带密码的压缩包最省事。5.5 爬虫采集慢到怀疑人生不是网速问题是限速策略写错了现象一晚上只抓了两三百篇文章进度条走得比树懒还慢。原因代码里每个请求都sleep(3)列表页、详情页、评论页统一延时串行执行大量时间浪费在等待上。更糟的是某些请求还失败重试重试又带着固定 3 秒延时雪上加霜。解决分级限速。列表页不需要频繁抓间隔 23 秒详情页和评论接口可以 0.51 秒随机延时批量抓取时用ThreadPoolExecutor开 46 个线程只对同一域名做全局数限速避免并发太高触发频控from concurrent.futures import ThreadPoolExecutor with ThreadPoolExecutor(max_workers5) as pool: pool.map(crawler.run_with_retry, docid_list)采集速度的正常范围是一小时 1000 到 3000 篇文章如果远低于这个数先看一下是不是每条详情页都发生了超时重试。超时重试的根源多半是目标网站响应慢把timeout调宽到 10 秒同时把重试次数降到 2 次效果远比无限重试好。记住一句话爬虫的速度瓶颈往往不在带宽而在重试和等待之间的平衡。6. 验收舆情平台的三个技巧让答辩老师愿意追问的可视化与验证方法6.1 一张图说明“热点是自己算的”而不是抄的答辩展示时至少准备三张图按日聚合的热度趋势折线图、高频词云图、情感分布堆叠图。热度趋势图最能说明问题因为它的横轴是时间纵轴是 4.2 节算出的final_score能直接体现时间衰减生效。具体做法是把所有新闻的pubtime按天分组对每天所有新闻的final_score求和用 pyecharts 的Line画出来。如果曲线在你设置半衰期后明显下降说明热度指数里的时间衰减项起作用了这张图就是论文里“舆情演化规律”的实证材料。6.2 用 pandas 做热点突增检测给平台一个可验证的“发现能力”舆情平台的价值在于能发现热点而不只是记录热点。一个简单但有效的验收方法是对评论数或热度值做滚动均值计算每个时间点的突增幅度超过阈值就标记为候选热点。代码可以短但逻辑要能对答如流。import pandas as pd df pd.read_sql(SELECT pubtime, comment_count FROM news_article, get_conn()) df[date] pd.to_datetime(df[pubtime]).dt.date daily df.groupby(date)[comment_count].sum().sort_index() window daily.rolling(3).mean() std daily.rolling(7).std() daily[(daily - window) 2 * std].index这里rolling(3).mean()是 3 天滑动平均2 * std是 2 倍标准差阈值。超过阈值的那几天就是评论量突增日把这些日期和当时的热门新闻标题列出来放进论文的验证章节。注意必须先用pd.to_datetime把时间字段转成 datetime 类型否则按天分组时字符串排序会打乱顺序这个错误我在好几个项目里都见过。6.3 把参数留痕写进论文热度公式要能回答“为什么是这个数”热点度公式里的每个权重、半衰期、情感阈值答辩时都会被追问来源。我的习惯是在源码根目录放一个params.yaml把所有实验过的参数记录成表格参数名、值、实验效果、最终取值。论文的 LW 里不要只贴公式要把参数表作为一个独立小节。这样做还有一层好处如果你想把平台从一个频道扩展到多个频道只需要调参而不需要改代码这个扩展性本身就是加分项。最后再提醒一句源码里涉及账号密码、数据库密码的配置建议挪到config.py提交前检查一遍不要泄露隐私——这算是带毕设这几年攒下来的一点职业习惯希望帮到你。本文还有配套的精品资源点击获取
返回列表