爬取小说网站
用 Python 的小说 requests 加 BeautifulSoup,三十行代码就能把一本连载小说从网站上拽下来。网站我上周试了试,小说目标是网站一个排版干净的盗版站,结果比预想的小说顺利。但这里面有几个坑,网站不踩不知道。小说
先看页面结构。网站那网站每章一个独立 URL,小说正文全塞在 <div id="content"> 里,网站段落用 <br> 分隔。小说没有 JavaScript 渲染,网站没有反爬 token,小说连 User-Agent 都不查。网站这种站就是小说给爬虫练手用的。
import requests from bs4 import BeautifulSoup url = "https://example.com/novel/12345.html" headers = { "User-Agent": "Mozilla/5.0"} resp = requests.get(url, headers=headers) resp.encoding = "utf-8" soup = BeautifulSoup(resp.text, "html.parser") content = soup.find("div", id="content") text = content.get_text("\n", strip=True) print(text[:500]) 跑通第一章只花了三分钟。问题出在批量下载。那本小说有 1200 多章,章节链接藏在 <select> 下拉框的 <option> 里。用 soup.find("select").find_all("option") 拿到所有 value,拼上域名前缀,列表就齐了。
但直接 for 循环请求 1200 次,到第 80 章左右开始报 403。网站有频率限制。加个 time.sleep(1.5) 能缓解,代价是下载整本要半小时。我改成每请求 50 章停 10 秒,反而更稳。这里有个细节:sleep 要放在请求之后、解析之前,让 TCP 连接自然关闭,比在循环开头 sleep 更不容易触发封禁。
另一个坑是编码。那网站有的章节是 GBK,有的是 UTF-8,混着来。requests 的 apparent_encoding 属性靠 chardet 猜,准确率大概九成。剩下那一成乱码章节,得手动试 resp.content.decode("gbk", errors="ignore")。我写了个小函数,先试 UTF-8,失败再试 GBK,最后兜底用 ignore 参数吞掉错误字符。
正文提取也有意外。有些章节末尾插了“请收藏本站”的广告行,还有的段落里混着 <a> 标签跳转到其他书。get_text() 会把链接文字也抓进来,得用 decompose() 先把 <a> 和 <script> 删掉。我一开始没管,结果导出的 txt 里全是“点击这里看下一章”。
存文件用 with open(f"{ chapter_num:04d}.txt", "w", encoding="utf-8") as f,章号补零方便排序。1200 个文件扔在一个文件夹里,Windows 资源管理器打开会卡。后来改成每 100 章建一个子目录,清爽多了。
最麻烦的其实是找章节列表。有的网站用 JavaScript 动态生成目录,requests 拿不到。这时候要么上 Selenium,要么直接分析它的 API。我遇到一个站,目录请求走的是 /api/chapters?book_id=xxx,返回 JSON。这种反而简单,requests.get 直接拿 JSON 解析,比解析 HTML 快十倍。
爬小说这事,技术难度不高,耐心占七成。你得一章一章对,看有没有漏、有没有乱码、有没有重复。我最后校对时发现有三章内容完全一样——网站自己贴错了。这种就只能手动补。
法律上别碰起点、晋江这些正版站。盗版站本身就在灰色地带,你爬它,它大概率不会告你,但也没啥可炫耀的。纯粹当练手,熟悉 requests 和 BeautifulSoup 的配合,知道怎么处理编码、限速、动态加载,就够了。真要看小说,充个会员比写爬虫省事。
(责任编辑:娱乐)














