资讯动态

爬虫数据可视化课设全套文件:requests+pyecharts完整流水线

发布时间:2026/10/18 19:47:57 来源:尧图企业网站定制
简介一份面向Python爬虫与数据可视化分析大作业的全套文件覆盖从网络抓取、HTML解析、数据清洗到数据可视化的完整链路适合高校信息类课程学生或Python数据分析初学者参考学习。压缩包内共5个文件包含1个核心Python脚本、1份docx格式的作业说明文档、1份停用词表以及2个gif动图整体大小仅2.72MB内容紧凑便于快速上手。目前已有1243人浏览学习反映出这套资料对同类大作业具有参考价值。配套的ReptilePyecharts.py脚本演示了如何用Requests与BeautifulSoup抓取网页、利用正则表达式提取信息再借助pandas完成数据清洗与预处理最后通过Pyecharts生成柱状图、折线图等可视化图表docx文档补充了项目设计与实现思路stopwords.txt为文本分析提供停用词表支撑两个gif则直观展示代码运行效果可帮助使用者快速验证结果。1. python 爬虫数据可视化大作业一套能直接交付的全套文件又是一个课设季总有人卡在同一个路口题目选的是 python 爬虫数据可视化分析爬虫吭哧吭哧写了两天数据倒是抓下来了结果卡在清洗、入库、画图这些环节上最后交上去的作业只有一张控制台截图。这套全套文件就是冲这个场景来的——它不是单个爬虫脚本而是一条从网页到最终可视化图表的完整流水线requests 抓取公开页面数据pandas 做清洗SQLite 落库pyecharts 生成能交互的图表再配上一份可以直接改写的报告骨架。你拿到手之后可以整套跑通也可以把它当模板换个数据源就是一份新作业。适合拿来做大作业参考也适合第一次完整走一遍爬虫数据可视化流程的人。2. 项目结构与技术选型六个文件撑起一条数据流水线2.1 全套文件清单每个文件负责哪个环节先看这套文件长什么样。解压之后是六个核心文件加一个数据目录各管一段路径和职责一目了然文件职责关键依赖spider.py网页抓取与字段解析输出结构化记录requests、BeautifulSoup4、lxmlclean.py数据清洗处理缺失值、类型转换、去重pandasdb.py建库建表负责 SQLite 的写入与增量更新sqlite3标准库analyze.py聚合统计并生成可视化图表pyecharts、pandasrequirements.txt一键安装全部依赖pipREADME.md运行步骤、文件说明、报告写法建议无data/ 目录在第一次运行 db.py 后自动生成里面是 books.db 和跑图表输出的 HTML 文件。这个分层是有意为之的每一层都能单独运行单独出问题单独排查不用每次从上到下全跑一遍。2.2 技术选型为什么是 requests pyecharts 而不是 scrapy matplotlib选型这步直接决定课设能不能在有限时间内做完。工程上 scrapy 当然更强大但课设场景里 requests 更合适——它的请求逻辑直白每一行都能在报告里讲清楚而且调试起来没有框架的额外概念负担。解析用 BeautifulSoup 加 lxml 解析器写起来比正则省心选择器写错报错也友好。可视化选 pyecharts 而不是 matplotlib核心原因是两个一是 matplotlib 出图要处理中文字体问题课设机器上没配字体就直接方块字二是 pyecharts 生成的是独立 HTML图表可以缩放、悬停、看数据评审时打开浏览器就能交互展示观感完全不一样。它基于 ECharts生成的图表在移动端打开也正常省去配 flask 的功夫。2.3 数据流向采集层、清洗层、展示层的协作方式整套文件按“采集 → 清洗 → 存储 → 分析展示”拆成四层层与层之间只通过文件或数据库交接不互相 import 业务函数。这样做的好处是每一层出错时黑匣子范围很小抓回来的数据不对问题在 spider.py写库之后数据不对问题在 clean.py。数据流向可以用下面这段伪代码描述# 数据流spider.py - clean.py - db.py - analyze.py # 网页HTML - DataFrame - SQLite表 - 图表HTML # 中间产物records.json爬虫输出 - books.db清洗后落库 - output/*.html分析结果spider.py 跑完会把原始记录写成一个 JSON 文件作为中间产物clean.py 读它而不是直接读网页这样爬虫和分析两件事完全解耦。你甚至可以单独换掉爬虫保留后面清洗分析的链路不动。实际踩坑时先看中间产物 JSON 是否正常再判断问题是出在抓取还是清洗效率比从头排查高得多。3. 爬虫模块实战requests lxml 把网页变成结构化数据3.1 请求构造UA、Referer 和频率控制不是玄学爬虫第一步是拿到一段“正常得像真人”的请求。很多站点会校验 User-Agent默认的 Python-requests 头很容易被识别直接拒掉。这里先构造一个 Session统一带上浏览器标识和来源页import requests from time import sleep HEADERS { User-Agent: ( Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 ), Referer: https://example.com/, } session requests.Session() session.headers.update(HEADERS) resp session.get(https://example.com/top, timeout10) resp.raise_for_status() sleep(1) # 控制请求频率别把对方服务器当循环测试机打这里有几个参数值得留意timeout 设成 10 秒避免某个页面卡住导致整个爬虫挂起raise_for_status() 会在返回 4xx/5xx 时直接抛异常让程序快速失败而不是拿着错误页面继续解析每条请求之间 sleep(1)是给服务器一个合理的间隔。别小看这行 sleep不少同学图快把它删了结果爬到一半 IP 被临时封掉整个抓取前功尽弃——这种反爬拦截主要是频率问题不是玄学。3.2 列表页解析CSS 选择器抽取书名、作者、评分请求拿到 HTML 之后接下来就是把页面里的信息“抠”出来。这里以某公开图书榜单为例榜单每页有若干条目每个条目包含书名、作者、出版社、评分、评论数、价格。用 BeautifulSoup 的 CSS 选择器可以实现字段抽取from bs4 import BeautifulSoup soup BeautifulSoup(resp.text, lxml) items soup.select(div.item) rows [] for item in items: title item.select_one(h3 a).get_text(stripTrue) author item.select_one(span.author).get_text(stripTrue) publisher item.select_one(span.publisher).get_text(stripTrue) rating_text item.select_one(span.rating).get_text(stripTrue) rating float(rating_text) if rating_text else None rows.append({ title: title, author: author, publisher: publisher, rating: rating, })这段逻辑的核心在 select_one 和 get_text(stripTrue) 的配合。select_one 返回第一个匹配 CSS 选择器的元素选不中时返回 None所以 rating 字段先判断再转 float否则页面上偶尔缺评分会直接让程序崩溃。get_text(stripTrue) 会把元素里的空白字符去掉得到干净的文本。不同网站的字段位置不同你只需要改括号里的选择器字符串——这是整个项目里唯一需要根据目标站点调整的地方。3.3 健壮性兜底超时重试与爬虫中断恢复课设网站通常稳定但网络波动和临时限流还是躲不掉。一个合格的爬虫脚本应该带重试机制而不是一遇上超时就“当场死亡”。这里给 fetch 动作包了一层指数退避重试def fetch_page(session, url, retries3): for attempt in range(retries): try: resp session.get(url, timeout10) resp.raise_for_status() return resp except (requests.Timeout, requests.ConnectionError) as e: if attempt retries - 1: raise wait 2 ** attempt print(f第 {attempt 1} 次失败{wait} 秒后重试...) sleep(wait) return None这段代码的关键逻辑是前两次失败分别等 1 秒、2 秒指数退避最后一次失败直接抛出异常让外层循环知道这个页面确实抓不动了。注意它只捕获 Timeout 和 ConnectionErrorHTTP 状态码错误由 raise_for_status 处理两类错误分开处理更清晰。有了这个函数多页抓取循环里只需要每页调用 fetch_page失败自动重试中间某页断了也能继续跑不会影响已抓取的数据。4. 存储与分析模块SQLite 落库 pyecharts 出图4.1 数据清洗去重、类型转换与缺失值处理爬虫抓回来的原始记录是字符串和散落字段直接入库会留下一堆坑书名重复、评分变成文本、价格带着货币符号。清洗这一步用 pandas 把一切拉回正轨。先看建表和唯一索引再看清洗逻辑CREATE TABLE IF NOT EXISTS books ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, author TEXT, publisher TEXT, rating REAL, price REAL, crawled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE UNIQUE INDEX IF NOT EXISTS idx_book_title ON books(title, author);唯一索引是防重复的关键。它把“书名 作者”组合设为唯一键后续再跑爬虫时数据库层面就会拒绝完全相同的记录避免重复数据越堆越多。接下来是清洗脚本import pandas as pd import sqlite3 df pd.DataFrame(rows) df df.drop_duplicates(subset[title, author]) df[rating] pd.to_numeric(df[rating], errorscoerce) df[price] df[price].str.replace(¥, , regexFalse).astype(float) df df.dropna(subset[title]) df.to_sql( books, sqlite3.connect(data/books.db), if_existsappend, indexFalse, )逐行看这里做了什么drop_duplicates 按书名和作者去重对应刚才的唯一索引pd.to_numeric 把“8.5”这种字符串转成浮点数转不了的置为 NaNprice 字段先去掉货币符号再转 float。最后 dropna 把没有书名的记录删掉因为那是无意义的脏数据。to_sql 用 if_existsappend 实现增量写入重复运行时不会覆盖历史数据配合唯一索引就构成了一套完整的防重复方案。4.2 聚合查询用 SQL 算出出版社 Top10 和评分分布数据入库后分析就有底气了。有了 books 表统计分析就是写 SQL 的事。这套文件里预置了几个分析维度都是答辩时容易被追问的统计口径-- 出版社图书数量 Top10 SELECT publisher, COUNT(*) AS cnt FROM books GROUP BY publisher ORDER BY cnt DESC LIMIT 10; -- 整体评分统计 SELECT AVG(rating), MAX(rating), MIN(rating) FROM books;第一个查询用 GROUP BY 按出版社分组COUNT(*) 统计每个出版社的图书数量按数量倒序取前十。第二个查询计算全量图书的平均分、最高分、最低分用来回答“这批数据整体水平怎么样”的提问。如果你想把分析扩展成“评分高于 9 分的书有多少”加 WHERE rating 9 即可。数据进了数据库分析维度就是 SQL 熟练度的问题而不是爬虫的问题了。4.3 可视化输出pyecharts 生成柱状图、饼图与散点图最终交付的图表由 analyze.py 统一生成它从数据库读数用 pyecharts 输出独立 HTML。下面这段是一个出版社 Top10 柱状图的核心代码import sqlite3 import pandas as pd from pyecharts.charts import Bar from pyecharts import options as opts conn sqlite3.connect(data/books.db) df pd.read_sql_query( SELECT publisher, COUNT(*) AS cnt FROM books GROUP BY publisher ORDER BY cnt DESC LIMIT 10, conn, ) bar Bar() bar.add_xaxis(df[publisher].tolist()) bar.add_yaxis(图书数量, df[cnt].tolist()) bar.set_global_opts( title_optsopts.TitleOpts(title出版社图书数量 Top10), xaxis_optsopts.AxisOpts(name出版社), yaxis_optsopts.AxisOpts(name数量), ) bar.render(output/publisher_top10.html)这段代码结构很固定先查库得到 DataFrame再把 DataFrame 的列传给 add_xaxis 和 add_yaxis最后设置坐标轴名称后渲染到 HTML。pyecharts 的图表类型可以整体替换——把 Bar 换成 Pie 就是饼图换成 Scatter 就是散点图数据传参接口保持一致。做评分价格散点图时只需要把 x 轴设为价格、y 轴设为评分就可以观察“贵的书评分是否一定高”这类关联性问题。5. 避坑记录从抓取到交作业最容易翻车的五个环节5.1 抓取环节的三类翻车现场现象一控制台打印出来全是乱码根本没法解析。原因requests 拿到的 resp.text 默认按响应头猜测编码而部分站点响应头没写 charset 或写得不准确导致中文被解码成乱码。 解决在解析之前加一行 resp.encoding resp.apparent_encoding让 requests 根据页面内容自动判断编码再不行就手动指定为 utf-8 或 gbk。现象二循环翻页结果翻来翻去抓到的是同一页的数据。原因翻页参数拼接错误。有的站点是 ?page2有的是 ?offset20还有的是 POST 请求里带参数。照抄别人的翻页代码而不看目标站点实际用的参数是典型的“看着对其实是错的”。 解决打开浏览器开发者工具在 Network 面板里点击第 2 页看实际发出的请求 URL 和表单参数照着拼接。抓完第 1 页后打印当前页的元素数量确认不是第 1 页的内容再继续。现象三爬了五十页后突然开始返回 403请求被拒。原因前半段正常后半段被风控识别为机器行为典型触发点是请求频率过高且一直用同一个 UA。 解决降低请求频率把 sleep 从 1 秒提高到 2-3 秒固定用完整 UA 头而不是默认的 Python 标识如果对方返回验证码页面停止程序不要尝试绕过验证码等一段时间再恢复抓取。5.2 存储与出图环节的常见问题现象四爬虫多跑了几次数据库里相同书籍出现了好几条。原因写入没有做去重每次跑脚本都往表里 insert 全部记录。这是不设唯一索引的必然结果。 解决在建表时加上 UNIQUE 索引并把 to_sql 的 if_exists 参数改为 append配合写入前 drop_duplicates三层保障可以确保同一本书不会重复落库。现象五图表做出来了标题和坐标轴中文全是方块英文正常。原因用了 matplotlib 但没有配置中文字体系统默认字体不支持中文。 解决换 pyecharts 出图它是基于 ECharts 的图表在浏览器里渲染字体跟着浏览器走不存在中文乱码问题如果坚持用 matplotlib需要手动下载中文字体文件并设置 rcParams 指向它比较折腾。6. 二次开发思路把通用模板换皮成自己的选题6.1 换选题三步走这套文件最大的价值不在“能跑”而在“好改”。想把它变成一份新选题的作业不需要动架构只要改三个地方。第一步把 spider.py 里的目标地址和选择器换成你的数据源。选定一个公开、稳定、不需要登录的信息型站点比如某个公开的排行榜或某类商品的列表页。在开发者工具里找到列表项的选择器映射成字段。第二步调整 clean.py 的字段映射表。图书项目的字段是书名、作者、出版社换选题后可能是“商品名、品牌、价格、销量”。映射逻辑不变只需要在解析代码里把字段名和选择器替换掉把类型转换的规则对应改一下。建议用统一的字段映射表后续维护选择和存储逻辑都方便。第三步改 analyze.py 的统计维度。换一个分组维度就换一条 GROUP BY 语句比如从“出版社 Top10”改成“品类销量占比”“评分价格散点图”改成“销量价格散点图”。图表的类型不用变换数据后重新 render 就是一张新图。字段映射可以按下面这种结构集中管理避免把选择器散在代码各处FIELD_MAP { title: (h3 a, text), author: (span.author, text), publisher: (span.publisher, text), rating: (span.rating, float), price: (span.price, price), }集中管理之后换数据源时只需要维护这一张表。清洗逻辑和存储结构不随业务字段变化而大改这是工程课设里很加分的意识。6.2 让作业更完整的两个加分项如果时间充裕还可以做两点增强。一是给 analyze.py 增加一个“对比图表”功能——把数据按不同年份分组分别生成综合对比柱状图这样报告里就能写“不同年份的趋势差异”章节。二是如果熟悉 Flask可以写一个约 50 行的 app.py把 output 目录下的图表 HTML 拼到一个页面上形成一个小型数据看板答辩时直接浏览器展示效果比贴静态截图好得多。说句个人的血泪经验我当年交完作业评审老师问了一句“换个网站还能跑吗”我当场愣住因为我当时把页面解析逻辑写死在一个函数里换站就得重写大半。从那以后我每次写爬虫相关的课设都强制把采集、清洗、展示三层拆开并且用一个集中的字段映射表做交接哪怕只是简单的课程作业也不例外。这不仅是给老师看的架构意识更是给下一个自己留的后悔药。希望这套文件能帮你少踩几个坑把时间花在真正值得讲的分析结论上。整套文件拉下来后照着 README 按顺序跑一遍再按这套思路换皮成自己的选题两个晚上就能交出一份结构完整、讲得清楚的作业。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑