资讯详情

资讯详情

基于Hadoop的网络小说数据分析系统:Python全链路设计与实现

这次我们来看一个 Python 计算机毕业设计项目基于 Hadoop 的网络小说数据分析系统。它的看点是技术链路完整不是某个算法有多难先写 Python 爬虫采集网络小说榜单和详情数据把数据落到 Hadoop HDFS 上做分布式存储再用离线分析计算分类趋势、作者排行、字数分布等指标接着用推荐算法生成“喜欢这本书的人还喜欢”的结果最后通过可视化大屏展示分析结论。爬虫、大数据框架、推荐算法、可视化四种能力全都有正因为链路完整这类项目在本科毕设答辩时反而比单点功能更容易讲清楚。先回答一个很多人会关心的问题这项目值不值得选或者拿到配套源码后该怎么下手。从工程角度看核心难点不在 Python 爬虫和 ECharts而在 Hadoop 环境的搭建和验证。只要能把 Hadoop 伪分布式跑起来数据写入 HDFS、执行分析 SQL、导出结果给 Web 层后续工作基本都是“调用服务 拼装数据 渲染图表”的组合。本文会从项目结构出发拆清楚数据流和各模块设计再给出本地环境准备、部署、测试、排错的完整思路适合准备大数据方向毕设、想要系统化梳理“Python Hadoop 推荐算法 可视化”套路的读者。如果把项目拆成几个关键特点可以这样看一是数据闭环完整采集、存储、计算、推荐、展示都有对应模块二是技术栈主流Python 负责数据处理和接口Hadoop/HDFS 承担分布式存储和离线分析三是可视化成果直观分析出的榜单和分布能直接放在答辩 PPT 里四是交付物结构比较全标题里已经写了包含源码、文档报告和代码讲解拿来对照学习或二次开发都会省去不少搭框架的时间。下面的步骤不会假定机器是 64G 内存集群单机伪分布式就足够把整条链路跑通。1. 核心能力速览能力项说明项目类型Python 计算机毕业设计 / 大数据离线分析方向技术栈Python、Hadoop、HDFS、推荐算法、Web 可视化数据采集爬虫采集网络小说榜单、分类、作者、字数、推荐票、简介等公开元数据存储层Hadoop HDFS 分布式文件存储伪分布式即可演示离线分析基于 Hadoop 生态做统计计算常见实现是 HiveSQL 或 MapReduce推荐模块基于小说分类/标签/用户行为建模的教学级推荐结果可视化通过 Web 页面展示分类占比、作者榜单、字数区间、推荐结果等交付物项目源码、文档报告、代码讲解运行环境单机伪分布式 Hadoop 即可建议 8G 内存以上开发机合规重点爬虫数据源必须合法默认只处理公开数据避免采集受版权保护的小说正文这里有一个需要说明的地方Hadoop 分析具体采用 HiveSQL 还是手写 MapReduce可视化后端用的是 Flask 还是 Django要看手上源码的实际实现。上面表格描述的是这类毕设项目最常见的落地轮廓代码讲解视频里一般也会先介绍这个顶层结构。2. 适用场景与使用边界这个项目更适合下面几类人Python 和 SQL 有基础想把 Hadoop 放进简历或毕业设计里的同学需要一个“数据从采集到展示”完整演示的项目而不是只写一个爬虫或只画几张图的读者以及正在搭建大数据综合课程设计想参考模块划分的人。项目中很多地方体现的是工程思维比如数据清洗要处理缺失值和重复数据CSV 直接分隔会因为小说简介里的逗号把字段拆坏Hive 表需要设计合适的分隔符这些都值得实际跑一遍。它的边界也非常清楚。第一脱胎于毕设场景不等于生产级小说数据分析平台数据量通常只有几万条性能方向不是重点。第二如果老师要求必须让“Hadoop”体现在重量级计算上那爬虫和数据可视化只是辅助核心得分点在于 HiveSQL 或 MapReduce 完成的分析任务不能把 Hadoop 当成普通文件存储来用。第三推荐算法带教学属性核心要讲清楚输入是什么、相似度怎么算、结果如何解释不能用“上线效果很好”这类无法验证的话。合规方面必须提醒一句网络小说正文通常有版权毕设项目尽量只处理榜单、书名、作者、分类、字数、评分等元数据不建议把全文内容采集进 HDFS。爬虫调用的站点要遵守 robots 协议和服务条款不绕过登录态、不暴力请求最稳妥的测试方式是本地构造一个 HTML 页面或者使用允许公开抓取的样例站点先验证解析逻辑再考虑扩大采集范围。演示和提交代码前也要去掉可能暴露隐私或涉及侵权的内容。3. 整体架构与技术选型从数据流方向看系统可以分为六个层次。层次职责常见选择采集层抓取小说列表页和详情页提取结构化字段Requests、Scrapy、BeautifulSoup预处理层去重、缺失值处理、字段标准化、中文分词关键词抽取Python、pandas、jieba存储层把清洗结果写入分布式文件系统Hadoop HDFS计算分析层离线统计分类数量、作者排行、字数分布等指标HiveSQL / MapReduce推荐层读取用户行为或小说属性计算 TopN 推荐协同过滤 / 内容相似度展示层为可视化页面提供数据接口并渲染图表Flask / Django ECharts一条完整的数据流转大概是这样的爬虫脚本先抓取页面并输出 JSON 或者 CSV然后数据预处理阶段清洗字段生成方便 Hive 读取的文本文件数据文件被上传到 HDFS 之后通过外部表让 Hive 能直接查询分析 SQL 跑完的结果落到 HDFS 的某个结果目录再导出到项目目录推荐模块读取这部分结果结合用户行为或小说属性和相似度算法生成推荐列表最终 Web 接口把分类统计、排行榜、推荐结果组合成 JSON前端用 ECharts 渲染大屏。这样的分层有一个优点每个模块都能被单独验证。爬虫可以离线路测清洗可以单独跑Hive 分析结果可以抽样核对可视化页面也能先用假数据调试。毕设调试时最忌讳把所有逻辑写在一个大 Python 文件里一旦 Hadoop 服务异常整个流程都定位不了问题。4. 核心功能模块设计4.1 爬虫采集模块爬虫模块的目的是把网页变成结构化数据。如果使用 Requests BeautifulSoup代码骨架一般长这样import json import time import requests from bs4 import BeautifulSoup def parse_novel_list(html_text): soup BeautifulSoup(html_text, html.parser) rows [] # 下面是通用写法最终选择器要根据目标页面结构调整 for item in soup.select(.book-item): title item.select_one(.title) author item.select_one(.author) if not title or not author: continue rows.append({ title: title.get_text(stripTrue), author: author.get_text(stripTrue), category: item.select_one(.category).get_text(stripTrue), intro: item.select_one(.intro).get_text(stripTrue), }) return rows def main(): headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)} all_rows [] for page in range(1, 11): # 页数需要控制避免给目标站点造成压力 url https://example.com/novel/list?page str(page) resp requests.get(url, headersheaders, timeout10) if resp.status_code ! 200: continue all_rows.extend(parse_novel_list(resp.text)) time.sleep(1) # 频率控制 with open(novels.json, w, encodingutf-8) as f: json.dump(all_rows, f, ensure_asciiFalse, indent2) print(collected:, len(all_rows)) if __name__ __main__: main()这里要解释清楚“双重合规”的必要性。第一层是法律合规没有站长授权就不要持续高频抓取更不要把抓下来的内容再公开传播第二层是工程合规很多流量稍微大一点的站点都会做频率限制和 User-Agent 校验如果一上来就跑几十个线程结果往往不是数据抓到了而是 IP 被临时限制随后代码可能什么也解析不出来。有些同学跑爬虫时会遇到一个很典型的现象程序执行结束显示 process finished with exit code 0但控制台没有任何输出。这不一定代表爬虫失败而是说明请求或解析环节静默地返回了空结果。比如目标页面改版后选择器没有命中又或者页面里根本没有.book-item这样的类名。调试时先打印状态码和 HTML 长度再检查解析结果条数比盲改选择器有效率得多。4.2 数据清洗与字段标准化爬虫原始结果里通常有大量问题同一本小说被重复采集、分类字段为空、简介里有换行符和多余空格、字数写成“123.4万字”而不是纯数字。如果不统一清洗后续上传 HDFS 和写 HiveSQL 都会踩坑。网络小说分析需要的典型字段包括字段含义示例novel_id小说唯一标识可由链接或平台编号生成nx10001title小说名称凡人修仙传author作者忘语category小说分类仙侠word_count字数建议统一为数字7600000click_count点击量12000000recommend_count推荐票/收藏数850000rating评分允许为空8.7intro简介作为推荐算法文本特征一个凡人踏上修仙之路……清洗代码可以按这样的思路组织import pandas as pd df pd.read_json(novels.json, encodingutf-8) # 去除重复小说 df df.drop_duplicates(subset[title, author]) # 去掉关键字段为空的行 df df.dropna(subset[title, author, category]) # 把“123.4万字”转成纯数字转换规则要按实际数据格式调整 df[word_count] df[word_count].astype(str).str.replace(万字, ).astype(float) * 10000 # 使用 \x01 作为 Hive 文本表分隔符避免小说简介里的逗号破坏列结构 df.to_csv(novel_clean.dat, sep\x01, indexFalse, encodingutf-8) print(df.shape)清洗后的数据要不要做中文分词取决于后续推荐算法是否使用简介关键词。如果只用分类做内容推荐分词不是必须的如果要做 TF-IDF 相似度则可以用 jieba 对intro分词把关键词结果存入单独的推荐特征文件。4.3 HDFS 存储与文件导入Hadoop 伪分布式环境准备好之后第一步不是急着写 MapReduce而是先把数据文件放进 HDFS确认读写过程没有异常。常用的操作是# 在 HDFS 上创建目录/user 下的实际路径以系统配置为准 hdfs dfs -mkdir -p /novel/ods # 上传清洗后的文本文件 hdfs dfs -put novel_clean.dat /novel/ods/ # 查看文件是否上传成功 hdfs dfs -ls /novel/ods/ # 如果 DataNode 容量或健康状态异常用这个命令检查 hdfs dfsadmin -report文件放进 HDFS 后可以在终端用hdfs dfs -cat查看内容确认是否为\001分隔。有经验的开发者会建议不在这一层直接建依赖文件夹结构的复杂目录而是先用一个/novel/ods目录跑通。因为伪分布式调试阶段最怕路径写错到后面再根据时间分区或来源网站扩展目录也不迟。4.4 Hive 建表与离线分析基于 Hadoop 的分析系统要想在答辩时站得住不能只把文件放到 HDFS 后就用 pandas 统计最好把核心指标计算放到 Hadoop 生态中。如果项目里使用了 Hive可以建一张外部表指向 HDFS 目录CREATE EXTERNAL TABLE IF NOT EXISTS novel_ods ( novel_id STRING, title STRING, author STRING, category STRING, word_count BIGINT, click_count BIGINT, recommend_count BIGINT, rating DOUBLE, intro STRING ) COMMENT 网络小说元数据外部表 ROW FORMAT DELIMITED FIELDS TERMINATED BY \001 STORED AS TEXTFILE LOCATION /novel/ods;建表字段必须和清洗文件列一一对应。这里有个常见错误文件里字段顺序是novel_id,title,author,category,word_count,click_count,recommend_count,rating,introHive 表却漏了某个字段结果查询出来的数据整体错位看起来像“中文乱码”或“全 NULL”。先SELECT * FROM novel_ods LIMIT 10;确认前几行再执行聚合 SQL。下面是一条典型的分组统计 SQL计算每个分类的小说数量、平均字数和平均评分SET hive.cli.print.headertrue; SELECT category, COUNT(*) AS cnt, ROUND(AVG(word_count)) AS avg_word_count, ROUND(AVG(rating), 2) AS avg_rating FROM novel_ods GROUP BY category ORDER BY cnt DESC LIMIT 20;这段 SQL 结果是可视化大屏中“分类分布”的数据来源。还可以继续扩展作者排行、字数区间、评分 Top 榜等 SQL但建议控制在一屏能展示的 6 到 10 个指标内避免报告越写越长。运行 HiveSQL 时命令行过程比较长可以把一段时间内重复执行的查询存成.hql文件统一管理hive -f hql/category_stats.hql logs/category_stats.log 21如果源码没有引入 Hive而是直接使用 Java MapReduce那么推荐用一个自定义 Mapper 做分类统计Reducer 做累加流程更绕但“分布式计算”的答辩说服力更强。具体实现要看项目配套代码这里不再展开伪代码因为 Hive 方案已经覆盖了同样效果。4.5 推荐算法模块推荐算法是该项目比较加分的点但也是容易被老师追问的部分。网络小说场景下最适合的教学级算法有两种一种是基于分类和简介关键词的内容相似度不需要用户行为适合“匿名浏览到详情页推荐相似书”另一种是基于用户收藏或评分数据的 ItemCF适合有模拟用户行为数据的系统。如果采用 ItemCF把用户对小说的行为看成一个评分矩阵先计算物品之间的相似度再根据用户看过的小说找到最相似的未看小说。下面是一个简化版本# 教学级 Item-Based Collaborative Filtering 简化示例 # 这里只是为了讲清楚算法逻辑实际数据应从用户行为表读取 ratings { userA: {novel1: 5, novel2: 3}, userB: {novel1: 4, novel3: 5}, userC: {novel2: 3, novel3: 4}, } def jaccard_similarity(items_a, items_b): union set(items_a) | set(items_b) if not union: return 0.0 inter set(items_a) set(items_b) return len(inter) / len(union) def recommend(user_id, top_n3): user_items set(ratings[user_id].keys()) item_scores {} for other_user, other_items in ratings.items(): if other_user user_id: continue sim jaccard_similarity(user_items, other_items.keys()) if sim 0: continue for item, score in other_items.items(): if item in user_items: continue item_scores[item] item_scores.get(item, 0) sim * score ranked sorted(item_scores.items(), keylambda x: x[1], reverseTrue) return ranked[:top_n] if __name__
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →