吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4970|回复: 43
收起左侧

[Python 原创] 半自动化给PDF加书签、目录-Python实现-可双击执行-上篇

  [复制链接]
ZDavy 发表于 2022-7-31 00:21
本帖最后由 ZDavy 于 2022-12-3 12:58 编辑

半自动化给PDF加书签、目录-Python实现-可双击执行-上篇



2022年11月22日更新 v0.60


下载链接:https://github.com/Davy-Zhou/pdf_add_bookmark_semi/releases/download/v0.60/pdf_add_bookmark_semi.v0.60.zip



如果觉得好用请Star:https://github.com/Davy-Zhou/pdf_add_bookmark_semi


针对页偏移无法识别时,增加页偏移输入选项,无需重开程序
针对多个PDF要加书签情况,完成一个PDF加书签后,无需重开,回车即可给下一个PDF加书签
书签格式化库规则更新


新更新:新增自动化获取书签和识别PDF页偏移功能,v0.51


链接:https://github.com/Davy-Zhou/pdf_add_bookmark_semi/releases/tag/v0.51

https://davy.lanzoub.com/b011viwih
密码:9hl7

本工具用途,可用于给没有书签的PDF加书签,主要应用于扫描版PDF,工具主要实现是格式化书签和加书签,
书签获取需要配合其它的软件,后期会考虑尽量在获取书签时自动化,页偏移部分也可自动化,格式化规则库
也会按大家的需求更新,当然也可自已加。完整的博客截图放在最后面了,图片大多了,真传不过来



工具界面



加了书签的示例


先前加书签的使用效果:https://www.52pojie.cn/thread-1665120-1-1.html

后面的部分,转成PDF放到网盘链接里面了

我把整个PDF转成图片了,看一下最后的图片,包含全部内容


如果访问不了,github也传了一份: https://github.com/Davy-Zhou/pdf_add_bookmark_semi
完整博客截图,github上也传了代码


# format_bookmark.py
[Python] 纯文本查看 复制代码
import subprocess
import re
import sys
#import os
from yaml import safe_load
from chardet import detect

# example
# input: python duxiu_regex.py C语言大学实用教程第4版.txt 17 12
# 3个参数 书签内容文件名 正文页偏移 目录页码

def format_bookmark():
    config_path=sys.argv[0]
    txt_filename=sys.argv[1]
    page_offset_number=sys.argv[2]
    if len(sys.argv)==4 :
        directory_number=sys.argv[3]
#    print('打开config.yaml','\n')
#    input('调试\n')
    with open(config_path+'\\Config\\config.yaml','r',encoding='utf-8') as f:
#        print(config_path+'\\Config\\config.yaml'+'\n')
#        input('调试\n')
        config=safe_load(f)                                      
#        检测编码GB18030、utf-8
        with open(txt_filename,'rb') as f:
            data = f.read()
            file_encoding = detect(data)['encoding']
            with open(str(txt_filename), 'r', encoding=file_encoding, errors = 'ignore') as f:
                str_list = f.read()
#                书签格式化
                for i in range(len(config['rules'])) :
                    for j in range(len(config['rules'][i]['rule'])):
                        regex_search=config['rules'][i]['rule'][j]['regex_search']
                        regex_repalce=config['rules'][i]['rule'][j]['regex_repalce']
                        if config['rules'][i]['rule'][j]['loaded'] and regex_search!=None and regex_repalce!=None:
                            regex_compiled = re.compile(regex_search, re.M)
                            str_list_re = regex_compiled.sub(regex_repalce, str_list)
                            str_list = str_list_re
#                    加页偏移,后面有页偏移是动态变量加不进yaml
                regex_page_offset = re.compile(r'(\d+)$', re.M)
                str_list = regex_page_offset.sub(r'\1\t+'+str(page_offset_number),str_list)
#                    路径保留空格
                filename=str(txt_filename).split('\\')[-1]
                path_name=str(txt_filename).split(filename)[0]
#                    文件名去空格?
                add_bookmark_filename = path_name+filename.replace(' ', '').split(
                    '.txt')[0]+r"(Bookmark)"+"."+filename.replace(' ', '').split('.')[-1]
                with open(add_bookmark_filename, 'w+', encoding='utf-8-sig') as fw:
                    if len(sys.argv) == 4:
                        if config['first_letter_lower']:
                            fw.write('目录\t'+str(directory_number)+'\n'+str_list.lower())
                        else:
                            fw.write('目录\t'+str(directory_number)+'\n'+str_list)
                    elif len(sys.argv)==3:
                        if config['first_letter_lower']:
                            fw.write(str_list.lower())
                        else:
                            fw.write(str_list)
#               初次格式化完书签,再次使用Notepad3编辑修正
                print("\n书签部分格式化完成,请在打开的编辑器修正书签文件,并\033[0;31;40m修正完后关闭编辑器!\033[0m\n")
                if config['enable_editor']:
                    editor_path=(config['editor_path'] if ':'  in config['editor_path'] else config_path+config['editor_path'])
                    subprocess.run([editor_path,add_bookmark_filename])

if __name__ == "__main__":
    format_bookmark()



#pdf_add_bookmark_semi.py
[Python] 纯文本查看 复制代码
import sys
import format_bookmark as fbk
from pikepdf import Pdf, OutlineItem
from colorama import init 
import os

def pike_add_bookmark():
    txt_filename=sys.argv[1]
    pdf_name = str(txt_filename).split('.txt')[0]+"."+"pdf"
    filename=str(txt_filename).split('\\')[-1]
    path_name=str(txt_filename).split(filename)[0]
    bookmark_filename = path_name+filename.replace(' ', '').split(
        '.txt')[0]+r"(Bookmark)"+"."+filename.replace(' ', '').split('.')[-1]

    with Pdf.open(pdf_name,allow_overwriting_input=True) as pdf:
        with pdf.open_outline() as outline:
            outline.root.clear() # 清空原PDF书签
            with open(bookmark_filename, 'r', encoding='utf-8-sig') as fb:
                for line in fb.readlines():          
                    txt_line = line.split('\t')
                    offset=''
                    if len(txt_line)>1:
                        offset = ((int(txt_line[-2]) + int(txt_line[-1]))
                                if txt_line[-2].isdigit() else  int(txt_line[-1]))-1
                    # 一级书签
                    # Page counts are zero-based
                    if txt_line[0] != '':
                        L1_item = OutlineItem(txt_line[0], offset)
                        outline.root.append(L1_item)
                    # 二级书签
                    elif txt_line[1] != '':
                        L2_item = OutlineItem(txt_line[1], offset)
                        L1_item.children.append(L2_item)
                    # 三级书签
                    elif txt_line[2] != '':
                        L3_item = OutlineItem(txt_line[2], offset)
                        L2_item.children.append(L3_item)
#                    四级书签
                    elif txt_line[3] != '':
                        L4_item = OutlineItem(txt_line[3], offset)
                        L3_item.children.append(L4_item)
        pdf.save(pdf_name)

if __name__ == "__main__":
#    方便双击使用
    init()
    if len(sys.argv)==1:
        print("\n请按格式输入:  \033[0;32;40m书签内容文件名 正文页偏移 目录页码(参数可选)\033[0m\n")
        print("使用示例:  \033[0;32;40m\"C语言大学实用教程第4版.txt\" 10 7 \033[0m\n\n")
        params =input("请输入: ").split('\"')
#        print(params,'\n')
#        input('调试\n')
        py_dirname, py_name = os.path.split(os.path.abspath(sys.argv[0]))
        sys.argv.clear()
        sys.argv.extend([py_dirname])
        sys.argv.extend([params[1]])
        sys.argv.extend(params[-1].split())
#        print(sys.argv,'\n')
#        input('调试\n')
    else:
        py_dirname, py_name = os.path.split(os.path.abspath(sys.argv[0]))
        sys.argv[0]=py_dirname
    filename=str(sys.argv[1]).split('\\')[-1].replace('txt','pdf')
#    print(filename,'\n')
#    input('调试\n')
    if len(sys.argv)<3 :
       print("\n错误:参数不足\n使用示例:  \"C语言大学实用教程第4版.txt\" 17 12\n或者:  \"C语言大学实用教程第4版.txt\" 17\n")
       sys.exit()
#    print('进入format_bookmark','\n')
#    input('调试\n')
    fbk.format_bookmark()
    print("是否给《\033[0;32;40m"+filename+"\033[0m》加书签(Y/N)?\n")
    is_add_Bookmark=input()
    if is_add_Bookmark.lower() != 'y':
        print("\n仅完成书签部分格式化!\n")
        print("\033[0;32;40m按Enter键退出!\033[0m\n")
        input()
        sys.exit()
    pike_add_bookmark()
    print("\n\033[0;32;40m"+filename+"\033[0m 加书签完成!\n\n")
    print("\033[0;32;40m按Enter键退出!\033[0m\n")
    input()














免费评分

参与人数 11威望 +1 吾爱币 +30 热心值 +10 收起 理由
JingHe0 + 1 谢谢@Thanks!
dmhsds + 1 谢谢@Thanks!
Wolre + 1 + 1 谢谢@Thanks!
Rocky10 + 3 + 1 用心讨论,共获提升!
jokerswift + 1 + 1 谢谢@Thanks!
笙若 + 1 + 1 谢谢@Thanks!
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
yyb414 + 1 + 1 热心回复!
lfm333 + 1 + 1 谢谢@Thanks!
观鱼 + 1 + 1 我很赞同!
function + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| ZDavy 发表于 2022-8-1 21:09
jokerswift 发表于 2022-8-1 15:57
楼主提个建议哈,一个是offset能不能自定义,有的上下册的pdf是分开的,下册的目录上的页数不是从1页开始的 ...

清空原PDF书签,这个功能已经加到贴子的代码里面了,就一行代码
outline.root.clear()
,pdf_add_bookmark_semi.py  那个文件第17行,我暂时不会提到github里面,整体的架构可能要改改,最开始拓展性没考虑好,添加这一行代码,里面很多东西都要受到影响,可能要两三天吧,如果你需要,自己加进去吧。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
Rocky10 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

 楼主| ZDavy 发表于 2022-8-6 23:45
Rocky10 发表于 2022-8-6 21:05
https://u.xueshu86.com/10075587.html
这个商家已经抓取了全部的书签,楼主研究下,是否可实现全自动化。

我看了下那个链接,书签只有部分显示,要全部显示,需要购买才行;抓包看了下,那个返回的书签应该也只返回了部分,完整的书签还在服务端,不付费拿不到。另外是超星的那个书签接口,我技术太菜了,分析不出来,后面我试一下用程序模拟点击的方法,把书签获取那部分尽量自动化了
sam喵喵 发表于 2022-7-31 00:32
function 发表于 2022-7-31 00:50
支持支持
lzspain 发表于 2022-7-31 07:19
扫描生成的PDF怕是不能实现吧
hahaleizi123 发表于 2022-7-31 07:40

技术贴一定要顶
studentguo 发表于 2022-7-31 08:40
学习。。。
lfm333 发表于 2022-7-31 09:38
感谢楼主分享
zhangsan2022 发表于 2022-7-31 11:37
必须支持,谢谢大佬的分享。。。
wuaidacongming 发表于 2022-7-31 11:42
技术贴一定要顶
 楼主| ZDavy 发表于 2022-7-31 12:35
sam喵喵 发表于 2022-7-31 00:32
为什么叫半自动化a

仔细看1.3节使用限制,书签获取,暂时只能手工,书签格式化,在规则库没丰富之前,有部分格式得自己调
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 15:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表