使用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做页面。
  • 当前只适配了希赛一个网站,根据后续需求增加程序的适配图片格式。
相关推荐
一个处女座的程序猿16 小时前
LLMs之PDF:zeroX(一款PDF到Markdown 的视觉模型转换工具)的简介、安装和使用方法、案例应用之详细攻略
pdf·markdown·zerox
Dxy123931021617 小时前
python下载pdf
数据库·python·pdf
周亚鑫17 小时前
vue3 pdf base64转成文件流打开
前端·javascript·pdf
一名技术极客18 小时前
Vue2 doc、excel、pdf、ppt、txt、图片以及视频等在线预览
pdf·powerpoint·excel·文件在线预览
S. Dylan1 天前
Edge浏览器打开PDF无法显示电子签章
edge·pdf
一马平川的大草原1 天前
如何基于pdf2image实现pdf批量转换为图片
计算机视觉·pdf·文件拆分
m0_594526301 天前
Python批量合并多个PDF
java·python·pdf
hairenjing11231 天前
将图片添加到 PDF 的 5 种方法
pdf
✿゚卡笨卡1 天前
pdf 添加页眉页脚,获取前五页
java·pdf
blegn1 天前
PDF编辑工具Adobe Acrobat DC 2023安装教程(附安装包)
pdf·办公软件·office