【Python 实战】一键爬取 HTML 文档并合并为完整 PDF

一、前言

在日常工作 / 学习中,我们经常会遇到本地离线 HTML 文档(如软件手册、技术文档、生成的静态网页),这些文档分散在多个 HTML 页面中,阅读、分享、归档都非常不方便。

手动将多个 HTML 转 PDF 再合并,效率极低且容易乱序。今天给大家分享一个Python 自动化脚本:✅ 自动爬取本地 HTML 所有子页面(递归遍历链接)✅ 自动按页面顺序转换为 PDF✅ 一键合并所有 PDF 为完整文档✅ 零报错、稳定兼容本地文件

二、核心依赖与工具准备

1. Python 依赖库安装

脚本依赖两个核心库,直接 pip 安装:

bash

运行

复制代码
pip install PyPDF2 beautifulsoup4
  • PyPDF2:用于 PDF 合并、文件操作
  • beautifulsoup4:用于解析 HTML 页面、提取链接

2. 必备工具:wkhtmltopdf

这是 HTML 转 PDF 的核心工具,必须提前安装

  1. 下载地址:https://wkhtmltopdf.org/downloads.html
  2. Windows 直接安装 exe,记住安装路径(后续脚本需要配置)
  3. 安装完成后,找到wkhtmltopdf.exe的完整路径(示例:C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe

三、完整脚本代码

直接复制使用,仅需修改配置区即可运行:

python

运行

复制代码
# -*- coding: utf-8 -*-
"""
@Author    : 技术笔记
@Desc      : 本地HTML文档递归爬取 + 批量转PDF + 自动合并
@Usage     : 仅修改BASE_URL、OUTPUT_PDF、WKHTML_PATH三个参数即可运行
"""
import os
import subprocess
from urllib.parse import urljoin, urlparse, unquote
from bs4 import BeautifulSoup
from PyPDF2 import PdfMerger

# ====================== 【核心配置:只改这里】 ======================
# 本地HTML入口文件路径(file:/// 开头,Windows路径格式)
BASE_URL = "file:///F:/Reference/pocketwave/pocketwave/cache/V1.0.0/docs/html/index.html"
# 最终合并PDF的保存路径
OUTPUT_PDF = "F:/pocketwave_full_docs.pdf"
# wkhtmltopdf 工具的exe路径(必须正确)
WKHTML_PATH = r"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe"
# ==================================================================

# 已访问页面集合 + 页面列表
visited = set()
pages = []

def url_to_local_path(file_url):
    """
    将 file:// 协议的URL 转换为 Windows本地文件路径
    """
    parsed = urlparse(file_url)
    path = unquote(parsed.path)
    path = path.lstrip('/')
    path = path.replace('/', '\\')
    return path

def crawl_links(url):
    """
    递归爬取所有HTML页面链接(自动去重)
    """
    if url in visited:
        return
    visited.add(url)

    try:
        # 转换为本地路径并校验文件是否存在
        file_path = url_to_local_path(url)
        if os.path.exists(file_path):
            print(f"📄 有效页面:{file_path}")
            pages.append(file_path)
        else:
            return

        # 解析HTML,提取所有a标签链接
        with open(file_path, "r", encoding="utf-8") as f:
            soup = BeautifulSoup(f.read(), "html.parser")

        # 遍历链接,过滤无效链接,递归爬取子页面
        for a_tag in soup.find_all("a", href=True):
            href = a_tag["href"]
            # 过滤锚点、外部链接
            if href.startswith("#") or href.startswith("http"):
                continue
            full_url = urljoin(url, href)
            # 只爬取HTML页面,自动去重
            if full_url.endswith(".html") and full_url not in visited:
                crawl_links(full_url)
    except Exception:
        pass

def convert_and_merge():
    """
    HTML批量转PDF + 自动合并 + 清理临时文件
    """
    temp_dir = "temp_pdfs"
    os.makedirs(temp_dir, exist_ok=True)
    temp_files = []

    print(f"\n🚀 开始转换 {len(pages)} 个页面...")

    # 逐个转换HTML为PDF(最稳定,无并发报错)
    for i, html_file in enumerate(pages):
        temp_pdf = os.path.join(temp_dir, f"page_{i:04d}.pdf")
        temp_files.append(temp_pdf)

        # wkhtmltopdf 转换命令
        cmd = [
            WKHTMLPATH,
            "--encoding", "UTF-8",  # 编码兼容中文
            "--enable-local-file-access",  # 允许访问本地文件(关键)
            html_file,
            temp_pdf
        ]

        # 执行转换
        subprocess.run(cmd, capture_output=True)
        print(f"✅ 已转换:{os.path.basename(html_file)}")

    # 合并所有PDF
    print("\n📦 正在合并成完整文档...")
    merger = PdfMerger()
    for pdf in temp_files:
        merger.append(pdf)
    merger.write(OUTPUT_PDF)
    merger.close()

    # 清理临时文件
    for f in temp_files:
        os.remove(f)
    os.rmdir(temp_dir)

    print(f"\n🎉 全部完成!PDF已保存至:{OUTPUT_PDF}")

if __name__ == "__main__":
    print("🔍 开始扫描所有HTML页面...\n")
    # 1. 递归爬取所有页面
    crawl_links(BASE_URL)
    # 2. 转换+合并PDF
    convert_and_merge()

四、使用教程(超简单)

1. 修改 3 个核心参数

只需要修改脚本中 **【核心配置】区域 **:

python

运行

复制代码
# 1. 你的本地HTML入口文件(必须以 file:/// 开头)
BASE_URL = "file:///你的HTML文档首页路径/index.html"
# 2. 最终PDF保存路径
OUTPUT_PDF = "你要保存的路径/文档名称.pdf"
# 3. 你安装的wkhtmltopdf.exe路径
WKHTML_PATH = r"你的wkhtmltopdf.exe路径"

2. 运行脚本

直接运行 Python 文件,控制台会输出:

  • 扫描到的所有 HTML 页面
  • 逐个转换进度
  • 合并完成提示

3. 效果展示

  1. 自动遍历所有子页面,无遗漏
  2. 按页面访问顺序生成 PDF,保证阅读顺序
  3. 自动清理临时文件,仅保留最终合并 PDF
  4. 完美兼容中文、本地图片、CSS 样式

五、关键知识点说明

1. 为什么用 file:/// 协议?

因为我们处理的是本地 HTML 文件 ,使用file:///协议可以让脚本正确解析本地路径,兼容 Windows 系统。

2. 转换参数说明

python

运行

复制代码
"--encoding", "UTF-8"  # 解决中文乱码问题
"--enable-local-file-access"  # 允许访问本地CSS、图片等资源,保证页面样式完整

3. 脚本优势

  • 递归爬取:自动遍历所有子页面,无需手动收集
  • 稳定无报错:单线程逐个转换,避免并发问题
  • 自动去重:避免重复转换、合并
  • 自动清理:不残留临时 PDF 文件
  • 兼容本地资源:支持页面中的图片、CSS 样式

六、常见问题解决

1. 报错:wkhtmltopdf 不是内部或外部命令

✅ 解决:WKHTML_PATH路径填写错误,检查 exe 文件是否存在,路径前加r避免转义。

2. 中文乱码

✅ 解决:脚本已配置UTF-8编码,确保你的 HTML 文件本身也是 UTF-8 编码。

3. 页面无样式 / 无图片

✅ 解决:必须保留--enable-local-file-access参数,允许访问本地资源。

4. 只爬取到首页,没有子页面

✅ 解决:检查 HTML 链接是否为相对路径,脚本已过滤外部链接和锚点,确保子页面是.html后缀。

七、总结

这个脚本完美解决了本地离线 HTML 文档批量转 PDF 合并的痛点,特别适合:

  • 软件离线帮助文档
  • 生成的静态技术手册
  • 本地多页 HTML 资料归档

只需要配置 3 个参数,一键运行,全自动处理,大大提升效率!

相关推荐
AI玫瑰助手1 小时前
Python基础:集合的定义、去重与交并差运算
开发语言·python·信息可视化
忡黑梨1 小时前
eNSP_DHCP配置
c语言·网络·c++·python·算法·网络安全·智能路由器
m0_741481782 小时前
Vue.js核心基础之响应式系统与虚拟DOM渲染关联机制
jvm·数据库·python
Magic-Yuan2 小时前
PySpark Debug 总结
人工智能·python·数据平台
skywalk81632 小时前
CodeArts碰到问题:CodeArts 智能体使用失败,显示:会话创建失败,请稍后重试
开发语言·python
Metaphor6922 小时前
使用 Python 查找并替换 Word 文档中的文本
python·c#·word
思考着亮2 小时前
8.Python 异常 (Exception)
python
是大强2 小时前
下载的jar怎么放到本地仓库
python·pycharm·jar
E_ICEBLUE2 小时前
在 Java 中使用 Spire.PDF 合并 PDF 文档(含加密与压缩处理)
java·pdf