python 自动识别pdf文件的目录
需求: 我学习的资料大多是pdf文件(pdf资料,论文等等。。),但是平时看pdf的时候,总是苦于一页页的翻页才能找到自己想看的章节。。。还是喜欢跟随目录 高速跳转到自己想看的章节去快速阅读。
很多朋友肯定也是基于目录的去看资料,但是当打开资源管理器的时候,又不知道资料是否带目录,带多少条目录。。。大大影响阅读效率。
本文就帮大家解决了这个问题 再文件名中插入目录标签信息前缀:
概念:
pdf文件的书签目录:TOC 即table of content
可以帮助读者快速跳转到感兴趣的章节去快速阅读。
1、用到的库:
pymupdf 可以获取pdf书签目录。
官方文档: https:// pymupdf.readthedocs.io/ en/latest/
安装:
pip install pymupdf
使用:
import fitz
使用这句来读取pdf的目录:
doc.get_toc()
做一个函数分析pdf的目录情况:
def sumTOC(pdf):
sumt = 0 #记录有效toc数量
tvalue = "" #设置书签评估标识
doc = fitz.open(pdf)
toc = doc.get_toc() #获取pdf目录
for t in toc:
if t[1].isdigit() or t[1].isspace(): #统计目录是数字,空格 pass。
else:
if len(t[1]) > 5:
sumt += 1 #其他情况 比如 中文 则累加 情况包括:中英文,特殊字符 都累加。
elif len(t[1]) < 5 :
#含有中文的书签,才会标记为有效书签并统计数量
for j in t[1] : #便利字符串 看是否有中文
if u'\u4e00' <= j <= u'\u9fff':
sumt += 1
print("短长度书签条目,但含有中文")
break
if sumt >0 and sumt <= 30:
tvalue = "+T30_"
elif sumt > 30 and sumt <= 80:
tvalue = "+T80_"
elif sumt > 80 and sumt <= 200:
tvalue = "+T200_"
elif sumt > 200 and sumt <= 500:
tvalue = "+T500_"
elif sumt > 500:
tvalue = "+T999_"
print("本书书签数量: " + str(sumt))
#print(tvalue)
doc.close()
return tvalue
解析:
使用for循环逐个分析书签目录,每一条书签目录提取出来是一个带三个元素的列表。['1','第一章xxxxx','xxxx']
我们需要的就是第二个元素,就是目录文字。 即
t[1]
然后判断这条目录是否有效,排除机器生成的001 002 这种不含内容的书签。
最后sumt变量保存统计完成的书签条数。
函数根据sumt变量,返回一个我们自己约定的标签值:比如0-30条目录的pdf,返回t30;31-80条目录的pdf,返回t80,。。。。
t999是大于800条书签的pdf。
后续我做了代码,实现了当前程序目录和子目录的批量判断,并以前缀的形式将返回值插入到了文件名中:
以后打开资源管理器,就能看到自己的资料带有多少目录了。方便了很多。
ok,话不多说,直接上完整代码:
# encoding=utf-8
#V0.2 修正:短长度书签条目没被识别的错误
#V0.2 修正:页数作为书签被判定为合法书签的错误。
#V0.2 新增:名字修正模块
#V0.2 修正:识别中报错。
#V0.2 修正:打包后闪退。
#v0.1 原型搭建完成 可以识别当前目录包含子目录中pdf的书签数量。
import fitz
import sys
from os.path import abspath, dirname
import os
import re
#打开一个pdf,获取有效书签的条数。
#参数: pdf 文件的参数名称
def sumTOC(pdf):
sumt = 0 #记录有效toc数量
tvalue = "" #设置书签评估标识
doc = fitz.open(pdf)
toc = doc.get_toc() #获取pdf目录
for t in toc:
if t[1].isdigit() or t[1].isspace(): #统计目录是数字,空格 pass。
else:
if len(t[1]) > 5:
sumt += 1 #其他情况 比如 中文 则累加 情况包括:中英文,特殊字符 都累加。
elif len(t[1]) < 5 :
#含有中文的书签,才会标记为有效书签并统计数量
for j in t[1] : #便利字符串 看是否有中文
if u'\u4e00' <= j <= u'\u9fff':
sumt += 1
print("短长度书签条目,但含有中文")
break
if sumt >0 and sumt <= 30:
tvalue = "+T30_"
elif sumt > 30 and sumt <= 80:
tvalue = "+T80_"
elif sumt > 80 and sumt <= 200:
tvalue = "+T200_"
elif sumt > 200 and sumt <= 500:
tvalue = "+T500_"
elif sumt > 500:
tvalue = "+T999_"
print("本书书签数量: " + str(sumt))
#print(tvalue)
doc.close()
return tvalue
#主函数,遍历当前程序目录 包括子文件夹 标识出标签数量。
#参数: root_path 程序根目录
def runToc(root_path):
for root, dirs, files in os.walk(root_path):
for filename in files: #遍历软件目录下得所有文件
if os.path.splitext(filename)[-1] == ".pdf" or os.path.splitext(filename)[-1] == ".PDF":
listFilename = filename.split('_')
fullName = os.path.join(root, filename) #组合 成当前pdf的完整路径
print(fullName)
#print(listFilename)
#print(listFilename[0])
firstName = listFilename[0]
#print(listFilename[1])
tv = sumTOC(os.path.join(root, filename)) #获取的pdf的数钱数量评价值标签文本 比如t30_ t50_ t80_ t200_
#如果没有进行过颜色识别,直接加前锥
if listFilename[0] == "black" or listFilename[0] == "rgb" or listFilename[0] == "other" or listFilename[0] == "text" or listFilename[0] == "gray":
listFilename1 =listFilename #复制一个变量 进行操作
listFilename1.pop(0) #删除名字列表 第一个元素 也就是 "rgb" 之类前缀
#print(listFilename)
#print(listFilename1)
a = '_'
newFilename = a.join(listFilename1) #去掉"rgb" 这些前缀 的新文件名。
ret = re.match('\+T\d+', newFilename) #含有+T30 等 等
if str(ret) == 'None' and tv != "": #没识别过书签数量,则文件名 加识别数量。
os.rename(fullName, os.path.join(root, (firstName + "_" + tv + newFilename)))
print("2222有特殊前缀pdf识别书签成功,改名成功")
#print(" ")
elif str(ret) == 'None' and tv == "": #无书签
print("无书签,跳过。。。。。 ")
elif str(ret) != 'None':
print("识别过书签,跳过。。。。")
except Exception as e:
print(e)
print("错误,书签识别加前缀失败")
else: # 文件名首字符串 不含有 rgb gray 等等 直接在文件名前面加t200 等等标签。
tv = sumTOC(os.path.join(root, filename)) #获取的pdf的数钱数量评价值标签文本 比如t30_ t50_ t80_ t200_
ret = re.match('\+T\d+', filename) #含有+T30 等 等
if str(ret) == 'None' and tv != "": #没识别过书签数量,则文件名 加识别数量。
os.rename(fullName, os.path.join(root,(tv + filename)))
print("1111无特殊前缀pdf识别书签成功,改名成功")
print(" ")
elif str(ret) == 'None' and tv == "": #无书签
print("无书签,跳过。。。。。 ")
elif str(ret) != 'None':
prihnt("识别过书签,跳过。。。。")
except Exception as e:
print(e)
print("错误,书签识别加前缀失败")
except Exception as e:
print(e)
print("错误,开始分析下一个pdf文件。。。。。")
if __name__ == '__main__':
if getattr(sys, 'frozen', False):