使用BeautifulSoup 4和Pillow合并网页图片到一个PDF:一种高效的方式来处理网页图像

背景

​ 网页上的培训材料,内容全是PPT页面图片。直接通过浏览器打印,会存在只打印第一页,并且把浏览器上无效信息也打印出来情况。但目标是希望将页面图片全部打印为pdf形式。

实现方案

  1. 利用网页"另存为",将页面内所有图片资源下载到本地;
  2. 利用页面html源码,解析出图片下载名与标准名之间对应关系;
  3. 格式化标准名,按文件名顺序排序;
  4. 按文件名顺序合并所有图片到一个pdf文件中。

技术点

  1. 利用BS4解析html文档
  2. 利用PIL的Image合并图片到pdf

操作步骤

  1. 打开页面并选择"另存为"。

  2. 保存到F:\course目录下

  3. 将所有图片文件复制到tmp目录

    通过分析页面图片,所有有效图片都是后缀为JPG格式的图片。

  4. 运行read_html.py文件,标准化tmp目录下图片文件名

    1、使用img标签下的alt文件名替换tmp目录下文件名。(本处实现,发现下载图片文件名为src下文件名,但alt属性中文件名更便于理解和排序)

    2、将文件名中编号规整,保持3位数字。(本处实现,最大的序号为366;名称为"幻灯片2.JPG"的会显示在"幻灯片11.JPG"的后面,需要将"幻灯片2.JPG'和"幻灯片11.JPG"规整为"幻灯片002.JPG"和"幻灯片011.JPG")

  5. 运行merge_img2pdf.py文件,将tmp目录下所有图片合并成一个pdf文件

源代码及注释

python 复制代码
# content of read_html.py
# 解析本地html文件,并将图片文件标准化命名
import re
import os
from bs4 import BeautifulSoup

def main():
    img_dict = {}
    soup = BeautifulSoup(open('个人中心-云阅读_希赛网.html')) # 读取另存为生成的html文件
    imgs = soup.find_all('img') # 获取所有img标签
    for img in imgs:
        if len(img['alt']) == 0:    # 过滤掉img标签中alt属性内容为空的字段
            continue
        real_name = img['alt']
        if len(real_name) == 9:     # 标准化img文件名,全部变为"幻灯片XXX.JPG"形式
            real_name = real_name[0:3]+'0'+real_name[3:]
        elif len(real_name) == 8:
            real_name = real_name[0:3]+'00'+real_name[3:]
        img_dict[os.path.basename(img['src'])] = real_name  # 构造字典,key为下载到本地的文件名,value为易读的待修改后的文件名
    print(img_dict)
    os.chdir('tmp') # 切换到tmp目录下
    for old_file_name, new_file_name in img_dict.items():
        if os.path.exists(old_file_name):   # 若实际文件存在才进行更名
            try:    # 增加异常捕获,alt属性名称存在同名情况,有发生异常风险。
                os.rename(old_file_name,new_file_name)  # 重命令文件
            except:
                pass
    
if __name__ == "__main__":
    main()
python 复制代码
# content of merge_img2pdf.py
# 遍历tmp下所有jpg文件,并在运行目录下生成pdf文件
from io import BytesIO
from PIL import Image
import os


def get_file_list():
    file_list = []
    for file in os.listdir():   # 遍历目录下所有JPG或jpg文件,并保存到file_list列表中,列表中图片顺序根据文件名称排序。
        if file.endswith('JPG') or file.endswith('jpg'):
            file_list.append(file)
    return file_list
    
def convert_to_pdf(file_list:list):
    sources = []
    output = Image.open(file_list[0])   # Image中加入第一张图片
    print(file_list)
    file_list.pop(0) # 从列表中去除第一张图片
    for file in file_list:
        file = Image.open(file) # 逐张打开图片
        if file.mode == "RGB":
            file = file.convert("RGB")
        sources.append(file) # 并添加到sources列表中
    os.chdir('..') # 返回程序运行目录
    output.save("output.pdf","pdf",save_all=True,append_images=sources) # 保存图片到pdf文件中,创建output时已经设置了第一张图片,append_images列表中按顺序保存了其它图片内容。
        
def main():
    os.chdir('tmp') # 进入tmp目录下
    file_list = get_file_list()
    convert_to_pdf(file_list)
    
if __name__ == "__main__":
    main()

后续优化

  • 目前是通过命令行方式运行,可以考虑通过pyside6做页面。
  • 当前只适配了希赛一个网站,根据后续需求增加程序的适配图片格式。
相关推荐
一只花里胡哨的程序猿1 天前
odoo打印pdf速度慢问题
pdf·odoo
灵海之森1 天前
Python将md转html,转pdf
pdf
阿幸软件杂货间1 天前
最新PDF版本!Acrobat Pro DC 2025,解压即用版
pdf·adobe acrobat·acrobat
星空的资源小屋2 天前
网易UU远程,免费电脑远程控制软件
人工智能·python·pdf·电脑
会飞的小菠菜2 天前
如何一次性将多个PPT幻灯片批量转换成PDF文档
pdf·powerpoint·ppt·批量·格式转换
somethingGoWay2 天前
wpf .netcore 导出pdf文件
pdf·wpf·.netcore
小白电脑技术2 天前
PDF教程|如何把想要的网页保存下来?
pdf·电脑
我没想到原来他们都是一堆坏人2 天前
通过Gen AI SDK调用gemini 2.5 pro,单独上传pdf文件 | ai agent 开发笔记 2025.9.2 Day 2
ai·google·pdf·sdk·gemini
AI视觉网奇2 天前
麒麟系统 doc转pdf
linux·运维·pdf
CodeCraft Studio3 天前
国产化PDF处理控件Spire.PDF教程:如何在 Java 中通过模板生成 PDF
java·python·pdf·spire.pdf·java创建pdf·从html创建pdf