使用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文件

    在这里插入图片描述

    在这里插入图片描述

源代码及注释

# content of read_html.py
# 解析本地html文件,并将图片文件标准化命名
import re
import os
from bs4 import BeautifulSoupdef 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属性内容为空的字段continuereal_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:passif __name__ == "__main__":main()
# content of merge_img2pdf.py
# 遍历tmp下所有jpg文件,并在运行目录下生成pdf文件
from io import BytesIO
from PIL import Image
import osdef 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_listdef 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做页面。
  • 当前只适配了希赛一个网站,根据后续需求增加程序的适配图片格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/213895.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

官宣!「湾区之光群星演唱会」拉开2024新年音乐华丽序幕!

万众期待,群星荟萃!青春宝安时尚湾区——湾区之光群星演唱会即将在2024年1月5日闪耀亮相深圳宝安。 华语歌坛巨星天后齐聚一堂,携手多位实力唱将,共同呈现一场无与伦比的演唱会盛宴!在深情而又充满力量的歌声之中&…

Linux修复磁盘坏道,重新挂载硬盘

修复磁盘 挂载报错: [rootlocalhost ~]$ mount /dev/sdb /mnt/mydevmount: /dev/sdb is write-protected, mounting read-only mount: wrong fs type, bad option, bad superblock on /dev/sdb,missing codepage or helper program, or other errorIn some cases …

15、lambda表达式、右值引用、移动语义

前言 返回值后置 auto 函数名 (形参表) ->decltype(表达式) lambda表达式 lambda表达式的名称是一个表达式 (外观类似函数),但本质绝非如此 语法规则 [捕获表] (参数表) 选项 -> 返回类型 { 函数体; }lambda表达式的本质 lambda表达式本质其实是一个类…

textarea文本框回车enter的时候自动提交表单,根据内容自动高度

切图网近期一个bootstrap5仿chatgpt页面的项目遇到的&#xff0c;textarea文本框回车enter的时候自动提交表单&#xff0c;根据内容自动高度&#xff0c;代码如下&#xff0c;亲测可用。 <textarea placeholder"Message ChatGPT…" name"" rows"&q…

TypeScript 第五节:条件语句

一、TypeScript 中常用的条件语句 TypeScript 的条件语句与 JavaScript 的条件语句类似&#xff0c;包括 if 语句、if...else 语句、switch 语句等。 1、if 语句 if 语句用于判断指定条件是否为 true&#xff0c;如果是 true&#xff0c;则执行一段代码块。 示例&#xff1a;…

命名空间this_thread

命名空间 - this_thread 在C11中不仅添加了线程类&#xff0c;还添加了一个关于线程的命名空间std::this_thread&#xff0c;在这个命名空间中提供了四个公共的成员函数&#xff0c;通过这些成员函数就可以对当前线程进行相关的操作了。 1.get_id() 调用命名空间std::this_t…

java脚本引擎Groovy动态执行

1.java脚本引擎Groovy实战_groovy脚本-CSDN博客 2.java可用的动态脚本引擎和动态代码执行_java动态执行代码片段-CSDN博客 3.Groovy动态加载Java代码的使用方法和工具类_groovy调用java类方法-CSDN博客 4.springboot应用动态运行groovy脚本-附源码 - 简书 (jianshu.com) 5.…

是不是学了低代码就自动放弃了高薪?内部资深解答来了!

目录 前言低代码开发&#xff1a;点餐还是自助烹饪&#xff1f;低代码的“菜单”低代码的局限性 市场影响的分析&#xff1a;一场关于低代码的对话低代码开发与程序员职业&#xff1a;名人视角解析总结 前言 近年来&#xff0c;低代码开发因其低门槛、高效率和易集成的特点受到…

conda 计算当前包的个数

Conda是一个强大的包管理器和环境管理器&#xff0c;它用于安装和管理来自不同源的软件包。若要计算当前conda环境中安装的包的数量&#xff0c;你可以使用以下命令&#xff1a; 首先&#xff0c;激活你想要检查的conda环境&#xff08;如果不是默认的base环境&#xff09;&am…

虹科新闻丨广州市“强企增效”项目助力虹科高质量发展!

来源&#xff1a;虹科电子科技有限公司 虹科新闻丨广州市“强企增效”项目助力虹科高质量发展&#xff01; 原文链接&#xff1a;https://mp.weixin.qq.com/s/9pUXx5ZZpIi5S4s4o90GJA 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; 2023年12月6日至7日&#xff0c;工…

hive/spark用法记录

1. cast()更改数据类型 cast(column_name as type) 2. get_dt_date()自定义日期操作函数&#xff08;返回不带横线的日期&#xff09; select get_dt_date();–获取当前日期&#xff0c;返回 20170209 select get_dt_date(get_date(-2));–获取当前日期偏移&#xff0c;转为…

如果将视频转化为gif格式图

1.选择视频转换GIF&#xff1a; 2.添加视频文件&#xff1a; 3.点击“开始”&#xff1a; 4.选择设置&#xff0c;将格式选择为1080P更加清晰&#xff1a; 5.输出后的效果图&#xff1a;

postgresql设置免密登录

您提供的步骤描述了在 PostgreSQL 数据库环境中配置服务器间的 SSH 无密码登录和数据库用户认证的过程。这些步骤主要用于设置一个高可用性、负载平衡的数据库集群环境。让我们逐一解释这些步骤的目的和应用场景&#xff1a; 1. 启动 PostgreSQL 服务 systemctl start postgr…

ReetrantReadWriteLock底层原理

文章目录 一、读写锁介绍二、ReentrantReadWriteLock底层原理1. 读写锁的设计 一、读写锁介绍 现实中有这样一种场景:对共享资源有读和写的操作&#xff0c;且写操作没有读操作那么频繁(读多写少)。在没有写操作的时候&#xff0c;多个线程同时读一个资源没有任何问题&#xf…

jQuery-操作DOM

使用jQuery操作DOM dom : 文档对象模型 就是HTML元素 $() 函数的2个用法: 用法1:放入一个字符串(选择器)表示获取元素 例如 $("p") $("#abc") $(".del") 用法2:放入一个函数&#xff0c;表示文档就绪函数 例如 $(function(){代…

TikTok挑战榜单:全球用户如何共襄盛举

TikTok作为全球最受欢迎的短视频应用之一&#xff0c;在这个平台上&#xff0c;用户们通过参与各种挑战&#xff0c;创造了无数令人惊叹的短视频。 本文将深入探讨TikTok挑战榜单的现象&#xff0c;探究全球用户如何共襄盛举&#xff0c;以及这种创意激发和社交互动如何成为Ti…

go-zero开发入门-API网关鉴权开发示例

本文是go-zero开发入门-API网关开发示例一文的延伸&#xff0c;继续之前请先阅读此文。 在项目根目录下创建子目录 middleware&#xff0c;在此目录下创建文件 auth.go&#xff0c;内容如下&#xff1a; // 鉴权中间件 package middlewareimport ("context""e…

前端开发常用的Vscode插件整理(持续更新)

本文记录用vscode进行前端开发时&#xff0c;常用到的有用的vscode插件&#xff0c;将不定时更新&#xff5e; 1、Chinese (Simplified) 将编辑器变成简体中文 2、vscode-icon 让 vscode 资源树目录加上图标&#xff0c;官方出品的图标库 3、Import Cost 引入包大小计算,对于…

Springboot Redis Lua 分布式限流器

pom文件中添加如下依赖包&#xff0c;比较关键的就是 spring-boot-starter-data-redis 和 spring-boot-starter-aop。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></d…

基于ssm实验室开放管理系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本实验室开放管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信…