使用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做页面。
  • 当前只适配了希赛一个网站,根据后续需求增加程序的适配图片格式。
相关推荐
itwangyang5205 小时前
2025 - 科研神器 - 批量处理 PDF、SVG、PNG 和 JPG 文件,将它们转换为彩色 TIFF 文件,并保存到指定的 tiff 文件夹中
数据库·pdf
maknul5 小时前
【学习笔记】AD智能PDF导出(装配文件)
笔记·学习·pdf
WCF向光而行6 小时前
如何为PDF文件创建口令密码
pdf
清山博客11 小时前
Java将PDF保存为图片
java·开发语言·pdf
life102411 小时前
pdf文档动态插入文字水印,45度角,旋转倾斜,位于文档中央,多行水印可插入中文
java·pdf·水印
归鸿铭11 小时前
Html 转pdf
java·pdf·html
wsd_ontheroad11 小时前
HTML 转 PDF
java·pdf·html
Java小王子呀17 小时前
java使用itext生成pdf
java·pdf
萧鼎20 小时前
轻松解析 PDF 文档:深入了解 Python 的 pdfplumber 库
服务器·python·pdf
初学者↑1 天前
在线pdf转word免费工具
pdf