背景
? 網頁上的培訓材料,內容全是PPT頁面圖片。直接通過瀏覽器打印,會存在只打印第一頁,并且把瀏覽器上無效信息也打印出來情況。但目標是希望將頁面圖片全部打印為pdf形式。
實現方案
- 利用網頁“另存為”,將頁面內所有圖片資源下載到本地;
- 利用頁面html源碼,解析出圖片下載名與標準名之間對應關系;
- 格式化標準名,按文件名順序排序;
- 按文件名順序合并所有圖片到一個pdf文件中。
技術點
- 利用BS4解析html文檔
- 利用PIL的Image合并圖片到pdf
操作步驟
-
打開頁面并選擇“另存為”。
-
保存到F:\course目錄下
-
將所有圖片文件復制到tmp目錄
通過分析頁面圖片,所有有效圖片都是后綴為JPG格式的圖片。
-
運行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“)
-
運行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做頁面。
- 當前只適配了希賽一個網站,根據后續需求增加程序的適配圖片格式。