小说爬虫实战:《斗罗大陆》章节自动抓取与合并

简介: 小说爬虫实战:《斗罗大陆》章节自动抓取与合并

在 Python 爬虫应用场景中,小说爬取是入门级且极具实用性的实战案例。《斗罗大陆》作为经典网络小说,章节数量多、内容结构清晰,非常适合用来讲解爬虫的核心逻辑与落地实现。本文将从需求分析、技术选型、代码实现到数据合并,完整拆解如何自动化抓取《斗罗大陆》全章节内容,并将分散的章节合并为完整的 TXT 文件,帮助你掌握爬虫开发的核心思路与实操技巧。
一、技术选型与核心思路

  1. 核心技术栈
    ● 请求库:requests(发送 HTTP 请求,获取小说网页源码)
    ● 解析库:BeautifulSoup4(解析 HTML 源码,提取章节标题与内容)
    ● 文件操作:Python 内置文件处理模块(保存单章节内容,合并全本)
    ● 反爬应对:设置请求头(User-Agent),模拟浏览器请求
  2. 核心实现思路
  3. 确定《斗罗大陆》小说的目标爬取站点(需选择结构清晰、无高强度反爬的站点);
  4. 爬取小说章节列表页,提取所有章节的标题与对应的 URL;
  5. 遍历章节 URL,逐个爬取章节内容,清理无关 HTML 标签,仅保留纯文本内容;
  6. 将每个章节的标题 + 内容保存为临时文件,或直接写入总文件;
  7. 合并所有章节内容,按章节顺序整理为完整的《斗罗大陆》TXT 文件。
    二、完整代码实现
  8. 环境准备
  9. 完整爬虫代码
    python
    运行
    ```import requests
    from bs4 import BeautifulSoup
    import time
    import os

配置项

替换为实际的《斗罗大陆》章节列表页URL(需选择稳定的站点)

BASE_URL = "https://example.com/douluo/"

请求头,模拟浏览器访问

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": BASE_URL,
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9"
}

===== 新增代理配置 =====

proxyHost = "www.16yun.cn"
proxyPort = "5445"
proxyUser = "16QMSOML"
proxyPass = "280651"

构建代理字典(同时支持http和https)

proxies = {
"http": f"http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}",
"https": f"https://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}"
}

保存路径

SAVE_DIR = "douluo_novel"

最终合并后的文件名

FINAL_FILE = "斗罗大陆-全本.txt"

def init_dir():
"""初始化保存目录"""
if not os.path.exists(SAVE_DIR):
os.makedirs(SAVE_DIR)

# 清空之前的临时文件(如果有)
if os.path.exists(os.path.join(SAVE_DIR, FINAL_FILE)):
    os.remove(os.path.join(SAVE_DIR, FINAL_FILE))

def get_chapter_list():
"""爬取章节列表,返回[(章节标题, 章节URL), ...]"""
chapter_list = []
try:

    # ===== 新增代理参数 proxies=proxies =====
    response = requests.get(BASE_URL, headers=HEADERS, proxies=proxies, timeout=10)
    response.encoding = response.apparent_encoding  # 自动识别编码
    soup = BeautifulSoup(response.text, "html.parser")

    # ******** 关键解析逻辑(需根据目标站点调整)********
    # 示例:假设章节列表在class为"chapter-list"的ul标签下,每个章节是li>a标签
    chapter_items = soup.find("ul", class_="chapter-list").find_all("li")
    for item in chapter_items:
        a_tag = item.find("a")
        if a_tag:
            chapter_title = a_tag.get_text().strip()  # 章节标题
            chapter_url = a_tag.get("href")  # 章节URL
            # 拼接完整URL(如果是相对路径)
            if not chapter_url.startswith("http"):
                chapter_url = BASE_URL + chapter_url
            chapter_list.append((chapter_title, chapter_url))
    print(f"成功获取{len(chapter_list)}个章节")
    return chapter_list
except Exception as e:
    print(f"获取章节列表失败:{e}")
    return []

def get_chapter_content(chapter_url):
"""爬取单个章节内容,返回纯文本内容"""
try:

    # 增加随机延迟,避免请求过快触发反爬
    time.sleep(0.5)
    # ===== 新增代理参数 proxies=proxies =====
    response = requests.get(chapter_url, headers=HEADERS, proxies=proxies, timeout=10)
    response.encoding = response.apparent_encoding
    soup = BeautifulSoup(response.text, "html.parser")

    # ******** 关键解析逻辑(需根据目标站点调整)********
    # 示例:章节内容在class为"content"的div标签下
    content_tag = soup.find("div", class_="content")
    if not content_tag:
        return ""

    # 清理无关标签(如广告、导航)
    for unwanted in content_tag.find_all(["script", "style", "div", "p"], class_=["ad", "nav"]):
        unwanted.extract()

    # 提取纯文本并格式化(去除多余空格、换行)
    content = content_tag.get_text().strip()
    # 替换多个换行为单个换行,保证格式整洁
    content = "\n".join([line.strip() for line in content.split("\n") if line.strip()])
    return content
except Exception as e:
    print(f"爬取章节失败 {chapter_url}:{e}")
    return ""

def save_chapter(chapter_title, chapter_content, index):
"""保存单个章节到总文件"""
final_path = os.path.join(SAVE_DIR, FINAL_FILE)

# 追加写入,编码为utf-8避免中文乱码
with open(final_path, "a", encoding="utf-8") as f:
    # 写入章节标题(带序号)
    f.write(f"===== {index}. {chapter_title} =====\n\n")
    # 写入章节内容
    f.write(chapter_content)
    # 章节间分隔
    f.write("\n\n")
print(f"已保存:{index}. {chapter_title}")

def main():
"""主函数:爬取+合并全本"""

# 初始化目录
init_dir()
# 获取章节列表
chapter_list = get_chapter_list()
if not chapter_list:
    print("未获取到章节列表,程序退出")
    return

# 遍历章节,逐个爬取并保存
for index, (title, url) in enumerate(chapter_list, 1):
    content = get_chapter_content(url)
    if content:
        save_chapter(title, content, index)
    else:
        print(f"跳过空章节:{title}")

print(f"\n爬取完成!全本已保存至:{os.path.join(SAVE_DIR, FINAL_FILE)}")

if name == "main":
main()

三、代码关键解析与适配说明
1. 核心函数解析
init_dir():初始化保存目录,确保文件存储路径存在,同时清理旧的全本文件,避免内容重复;
get_chapter_list():核心是解析章节列表页,提取所有章节的标题和 URL。需重点注意:不同小说站点的 HTML 结构不同,你需要根据目标站点的源码调整find()/find_all()的参数(如 class 名称、标签类型);
get_chapter_content():爬取单章节内容,先通过 requests 获取页面源码,再用 BeautifulSoup 解析核心内容区,同时清理广告、脚本等无关标签,保证内容纯净;
save_chapter():采用 “追加写入” 模式将章节内容写入总文件,避免多次打开关闭文件,提升效率,同时通过utf-8编码解决中文乱码问题;
main():串联整个流程,从初始化到章节爬取、保存,形成完整的执行链路。
2. 适配目标站点的关键调整
代码中标记********的部分是需要你根据实际爬取站点调整的核心解析逻辑,操作步骤如下:
打开目标小说站点的章节列表页,按 F12 打开开发者工具;
定位章节列表的 HTML 标签(如 ul/li/a),记录其 class/id 属性;
打开单个章节页,定位内容区的核心标签(如 div.content),替换代码中的解析参数;
测试爬取 1-2 个章节,验证内容提取是否准确,再批量爬取全本。
四、反爬应对与注意事项
请求频率控制:代码中加入time.sleep(0.5),避免短时间内大量请求触发站点反爬机制,可根据站点宽松程度调整延迟时间(0.5-2 秒);
请求头伪装:设置完整的 User-Agent、Referer 等参数,模拟真实浏览器请求,避免被识别为爬虫;
编码处理:使用response.apparent_encoding自动识别页面编码,解决中文乱码问题;
合规性说明:本爬虫仅用于技术学习,爬取内容请勿用于商业用途,且需遵守目标站点的 robots 协议,避免违规爬取。
五、效果验证
运行代码后,会在当前目录下生成douluo_novel文件夹,其中的《斗罗大陆 - 全本.txt》即为合并后的完整小说文件。打开文件可看到:
plaintext

```===== 1. 第一章 斗罗世界 =====

唐门外门弟子唐三,因偷学内门绝学为唐门所不容,跳崖明志时却发现没有死,反而以另外一个身份来到了另一个世界,一个属于武魂的世界,名叫斗罗大陆。

这里没有魔法,没有斗气,没有武术,却有神奇的武魂。每个人在六岁的时候,都会在武魂殿中令武魂觉醒。武魂有动物,有植物,有器物,武魂可以辅助人们的日常生活。而其中一些特别出色的武魂却可以用来修炼并进行战斗,这个职业,是斗罗大陆上最为强大也是最荣耀的职业——魂师。

===== 2. 第二章 武魂觉醒 =====

...

所有章节按顺序排列,内容无多余广告、格式整洁,实现了 “自动抓取 + 合并” 的核心目标。
总结

  1. 本次实战通过 requests+BeautifulSoup 实现了《斗罗大陆》小说的自动爬取,核心逻辑是 “解析章节列表→爬取单章节内容→追加写入合并文件”;
  2. 适配不同小说站点的关键是调整 HTML 解析参数,需结合开发者工具分析目标站点的标签结构;
  3. 爬虫开发需注意请求频率控制、编码处理和合规性,避免触发反爬或违规风险。
相关文章
|
6月前
|
数据采集 Web App开发 开发者
解决 Python 爬虫被限制:延迟抓取指令深度解析
解决 Python 爬虫被限制:延迟抓取指令深度解析
|
8月前
|
数据采集 人工智能 自然语言处理
架构演进:从确定性工作流 (Workflow) 到自主智能体 (LLM Agent)
本文对比生成式AI中Workflow(确定性流程)与Agent(自主推理系统)的技术范式,以“智慧旅游规划”为案例,剖析二者在控制流、状态管理与不确定性处理上的本质差异,揭示其适用场景与融合实践路径。
1218 2
|
2月前
|
人工智能 监控 API
AI Agent 技术全景:从核心原理到工程落地,开发者必须掌握的关键要点
AI Agent 技术全景:从核心原理到工程落地,开发者必须掌握的关键要点
|
8月前
|
数据采集 JSON API
Python 进阶爬虫:解析知识星球 API
Python 进阶爬虫:解析知识星球 API
|
9月前
|
数据采集 JSON Java
Java 异步爬虫高效获取小红书短视频内容
Java 异步爬虫高效获取小红书短视频内容
|
4月前
|
JSON BI 调度
Python + 大模型行业资讯自动化摘要流水线完整工程实现方案
Python + 大模型行业资讯自动化摘要流水线完整工程实现方案
|
3月前
|
数据采集 安全 Java
Python多线程深度避坑指南:GIL原理、并发陷阱与生产级最优解法
Python多线程深度避坑指南:GIL原理、并发陷阱与生产级最优解法
|
4月前
|
数据采集 JSON API
半小时学会 Python 爬虫:从零爬取知乎实时热榜榜单
半小时学会 Python 爬虫:从零爬取知乎实时热榜榜单
|
6月前
|
存储 API 数据安全/隐私保护
Python 自动化爬取网易云音乐歌手歌词实战教程
Python 自动化爬取网易云音乐歌手歌词实战教程
|
6月前
|
数据采集 存储 数据安全/隐私保护
Python 爬取图片攻略:告别水印,批量保存高清图片
Python 爬取图片攻略:告别水印,批量保存高清图片