最近在整理网文数据的时候,发现很多人卡在同一个环节:榜单数据拿到了,但不知道怎么系统地管理、更新和展示。单纯写个脚本跑一遍只能拿到一次性结果,等下次榜单刷新又要手动跑,数据一多还会遇到重复、字段错乱、格式不一致的问题。我自己的做法是用 Django 作为整个数据提取项目的底座,把请求、解析、入库、展示串成一条线,顺便把 Top500 小说数据做成一个可持续维护的小系统。
这篇文章就完整记录这个项目的设计与实现过程,覆盖从起点中文网榜单页面分析到 Django 模型设计、爬虫代码编写、定时调度、后台管理和 CSV 导出的全部环节。适合正在学 Python 数据提取的读者,也适合想在 Django 里集成爬虫逻辑、但不想引入 Scrapy 等重型框架的开发者参考。
在开始之前先说清楚:项目目标是提取起点中文网 Top500 小说榜单的基本信息,包括排名、书名、作者、分类、字数、状态和简介,并把数据持久化到本地数据库,方便后续查询和分析。整个项目基于 Python 3 和 Django 实现,不依赖复杂组件。
1. 提取目标拆解:起点Top500榜单到底有哪些数据
1.1 榜单页面的结构与数据来源确认
动笔写代码之前,先花时间把页面结构看清楚。起点中文网的排名体系比较多,有热度榜、月票榜、推荐榜等,Top500 一般指榜单前 500 名。我这次处理的是热门小说排名页面,每页展示 50 条左右,500 条数据大概要翻 10 页。
这里有个关键判断:页面上的数据是服务端直接渲染在 HTML 里,还是前端通过异步接口动态加载。打开浏览器开发者工具的 Elements 面板,如果在页面上看到的小说排名、书名、作者都直接出现在 HTML 源代码中,那就是第一种,用 requests 抓 HTML 后直接解析即可。如果页面显示数据,但 HTML 源码里找不到,就需要去 Network 面板看 XHR 请求,通常能找到返回 JSON 数据的接口。
起点这类页面的榜单数据,通常是由页面接口动态返回的,但也有服务端渲染的部分。我的建议是不要凭空假设,抓一次页面把响应内容打印前两千个字符,看看里面有没有书名和作者信息,再定解析方案。这一步做对了,后面能省很多反复调试的时间。
1.2 数据结构反推:页面字段与存储字段的映射
页面上的每条榜单信息,通常包含排名、书名、作者、分类、简介、字数、连载状态、详情页链接这几个核心字段。这些字段基本都能直接映射到表结构里。
在设计阶段就应该考虑清楚:哪些字段是必须的,哪些字段是可有可无的。我的经验是,排名、书名、作者、分类、详情页链接是必选,字数、状态、简介属于加分项。简介虽然有长有短,但对后续做文本分析很有价值,建议存下。详情页链接还可以作为唯一标识的一部分,因为同一本书通常只有一个详情页地址。
1.3 频率、访问规范与请求头准备
做公开数据抓取,最忌讳的就是高频率短时间冲击对方服务器。Top500 榜单一天抓一次完全足够,榜单更新频率远低于你的想象。抓取时每页之间随机 sleep 1~3 秒,不要用固定间隔,更不要并发开十几个线程去抢。这个项目的数据量只有 500 条,串行完全够用。
请求头至少要带上 User-Agent 和 Accept-Language,默认的 Python-requests UA 很容易被拦截。User-Agent 用浏览器的标准字符串,Referer 设置成榜单页本身的地址,这样整个请求看起来更像正常访问。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术选型:为什么用Django承载数据提取逻辑
2.1 Django、Scrapy与纯脚本的边界
很多人一听说爬虫就想到 Scrapy,但 Scrapy 适合的是大规模、分布式、需要中间件和管道机制的爬取场景。这个项目的数据量有限,反而需要的是数据管理、展示 API、后台维护这些能力,这些恰好是 Django 的强项。
如果用纯脚本,requests 跑完得到一堆字典,存 CSV 或 JSON 文件,也能完成任务,但后期做增量更新、字段校验、去重统计会非常别扭。Django 提供的 ORM、迁移机制、Admin 后台可以让数据的整个生命周期都处于可控状态。一句话总结:Scrapy 解决的是“怎么爬到更多数据”,Django 解决的是“爬到的数据怎么管理好”。
2.2 项目结构与App拆分
项目结构上,我建议把爬虫逻辑独立成一个模块,不要写在 view 或 model 里。
code复制novel_top500/
├── manage.py
├── config/
│ ├── settings.py
│ └── urls.py
├── novels/
│ ├── models.py
│ ├── views.py
│ ├── admin.py
│ ├── management/
│ │ └── commands/
│ │ └── fetch_top500.py
│ └── spiders/
│ ├── qidian.py
│ └── parser.py
spiders 目录放抓取和解析逻辑,management/commands 放 Django 命令入口,这样既能用 python manage.py fetch_top500 手动触发,也能接入 crontab 定时执行。不要把 requests 代码直接写到 view 里,否则页面刷新一次就触发一次抓取,非常容易被对方服务器拉黑。
2.3 依赖版本与虚拟环境
Django 版本我用的 4.x,Python 3.10 以上。requests、BeautifulSoup4、lxml 是解析侧的核心依赖。建议在项目根目录准备 requirements.txt,方便部署时一次性安装。
虚拟环境一定要用,隔离不同项目的依赖版本。Django 的版本差异对模型定义和 admin 写法多少有点影响,固定版本能少踩很多坑。
3. 数据模型设计:Top500榜单的字段取舍与约束
3.1 模型字段设计
模型设计是整个项目最关键的一环。字段太少,后续分析不够用;字段太宽,抓
