今天下载了一个英文pdf书籍,但书签全是大写英文字母,看上去有点别扭,于是想办法用自动化重命名pdf书签,

使书签全部变成首字母大写。

pdf原始书签如下图:

重命名后的pdf书签

自动化动态效果图,两三分钟完成重命名工作。

下面介绍下自动化过程。

uiautomation是我封装的python调用UIAutomation的module,参考 http://www.cnblogs.com/Yinkaisheng/p/3444132.html

运行automation.py -h查看帮助

先使用automation.py -a 获取pdf书签树控件的层次结构,-a参数 是获取光标下的控件,并一直获取父控件直到顶层窗口

在cmd里输入automation.py -a回车后,马上把鼠标移到pdf书签上,3秒后,将打印出控件树

再用此方法获取右键pdf书签右键菜单的控件树层次结构。

最后代码如下:

#!python3
# -*- coding: utf-8 -*-
# rename pdf bookmarks with FoxitReader 6.2.3
import time
import string
import automation TreeDepth = 2 #书签树只有前两层需要重命名
UpperWords = {
'amd': 'AMD',
'arp': 'ARP',
'dhcp': 'DHCP',
'dns': 'DNS',
'ip': 'IP',
'mac': 'MAC',
'unix': 'UNIX',
'pc': 'PC',
'pcs': 'PCs',
'tcp': 'TCP',
'tcp/ip': 'TCP/IP',
'vs': 'VS',
}
LowerWords = ['a', 'an', 'and', 'at', 'for', 'in', 'of', 'the', 'to'] class BookMark():
def __init__(self, name, newName):
self.name = name
self.newName = newName
self.children = [] def main():
window = automation.WindowControl(searchDepth= 1, ClassName= 'classFoxitReader')
window.SetActive()
time.sleep(1)
tree = automation.TreeControl(searchFromControl= window, ClassName= 'SysTreeView32')
childItems = tree.GetChildren()
bookMarks = []
depth = 1
for treeItem in childItems:
if treeItem.ControlType == automation.ControlType.TreeItemControl:
RenameTreeItem(tree, treeItem, bookMarks, depth)
fout = open('rename_pdf_bookmark.txt', 'wt', encoding= 'utf-8')
depth = 1
for bookMark in bookMarks:
DumpBookMark(fout, bookMark, depth)
fout.close() def DumpBookMark(fout, bookMark, depth):
fout.write(' ' * (depth - 1) * 4 + bookMark.newName + '\n')
for child in bookMark.children:
DumpBookMark(fout, child, depth + 1) def RenameTreeItem(tree, treeItem, bookMarks, depth):
treeItem.ScrollIntoView()
if depth > TreeDepth:
return
name = treeItem.Name
newName = Rename(name)
bookMark = BookMark(name, newName)
bookMarks.append(bookMark)
if newName != name:
treeItem.RightClick()
# FoxitReader书签右键菜单(BCGPToolBar,非Windows菜单)弹出后,枚举不到菜单,但从屏幕点上ControlFromPoint能获取到菜单, todo
# 采用特殊处理获取重命名菜单
time.sleep(0.2)
x, y = automation.Win32API.GetCursorPos()
menuItem = automation.ControlFromPoint(x + 2, y + 2)
if menuItem.ControlType == automation.ControlType.MenuItemControl:
#鼠标右下方弹出菜单
while not (menuItem.Name == '重命名(R)' or menuItem.Name == 'Rename'):
y += 20
menuItem = automation.ControlFromPoint(x + 2, y)
else:
#鼠标右上方弹出菜单
menuItem = automation.ControlFromPoint(x + 2, y - 2)
while not (menuItem.Name == '重命名(R)' or menuItem.Name == 'Rename'):
y -= 20
menuItem = automation.ControlFromPoint(x + 2, y)
menuItem.Click()
edit = automation.EditControl(searchFromControl= tree, searchDepth= 1)
edit.SetValue(newName)
automation.Win32API.SendKeys('{Enter}')
print('rename "{0}" to "{1}"'.format(name, newName))
if depth + 1 > TreeDepth:
return
treeItem.Expand()
childItems = treeItem.GetChildren()
if childItems:
treeItem.Expand()
for child in childItems:
RenameTreeItem(tree, child, bookMark.children, depth + 1) def Rename(name):
newName = name.strip().replace('\n', ' ')
#将CHAPTER 10变成10,删除前置CHAPTER
if newName.startswith('CHAPTER '):
newName = newName[len('CHAPTER '):]
newName = newName.title()
words = newName.split()
skipIndex = 1 if words[0][-1].isdigit() else 0
for i in range(len(words)):
lowerWord = words[i].lower()
start_punctuation = ''
end_punctuation = ''
if lowerWord[0] in string.punctuation:
start_punctuation = lowerWord[0]
lowerWord = lowerWord[1:]
if lowerWord[-1] in string.punctuation:
end_punctuation = lowerWord[-1]
lowerWord = lowerWord[:-1]
if lowerWord in UpperWords:
words[i] = start_punctuation + UpperWords[lowerWord] + end_punctuation
continue
if i > skipIndex and lowerWord in LowerWords:
if words[i-1][-1] != ':':
words[i] = lowerWord
newName = ' '.join(words)
return newName if __name__ == '__main__':
main()
input('\npress enter to exit')

  代码可在https://git.oschina.net/yinkaisheng/PythonUIAutomation4Windows 或 GitHub下载

另外此代码是根据FoxReader6.2.3实现的,其它版本不一定支持。

还有运行此程序时要关闭迅雷,在测试时发现如果运行了迅雷,会使pdf右键菜单获取有问题。

使用uiautomation自动化重命名pdf书签,使全大写字母变成首字母大写的更多相关文章

  1. 重命名PDF打印文件名

    Odoo系统默认打印出来的PDF文件都是以当前文档模型对象对应的模板文件名命名的,对用户来说,这样的命名很不友好. 我们希望能够将打印出来的文件名以单号命名,下面是实现这种目的的方法. 在report ...

  2. C# 文件重命名

    记得C# File类中是没有rename这个方法 所以网上很多都用的是move moveTo copy+delete等这些方法 其实以上的方法 虽然可以实现功能 但看起来总觉得很蛋疼 今天百度 突然发 ...

  3. C# rename方法重命名文件

    记得C# File类中是没有rename这个方法 所以网上很多都用的是move moveTo copy+delete等这些方法 其实以上的方法 虽然可以实现功能 但看起来总觉得很蛋疼 今天百度 突然发 ...

  4. linux安装PyCharm,PyCharm常用快捷键及调试模式,pycharm里面对文件夹或者文件进行重命名

    PyCharm常用快捷键及调试模式 2017年10月18日 23:13:43 菜鸟之神 阅读数:5835    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn ...

  5. linux下rename用法--批量重命名

    Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Linux发行版基本上使用的是C语言版本的,现在已经很难见到C语言版本的了, 由于历史原因,在Perl语言 ...

  6. linux下rename用法--批量重命名 转

    原文地址:https://www.cnblogs.com/hester/p/5615871.html Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Li ...

  7. 苹果系统OSX中Automator批量重命名

    Automator,看字面意思就无比强大,[自动机器].有什么能比自动还让人着魔? 答案是没有✔ 如果你用的是mac,如果你有一堆文件要重新整理命名,如果你还在Goole什么"批量重命名软件 ...

  8. lr文件下载脚本(文件参数化重命名)

    http://wenku.baidu.com/link?url=6oiIadyF9eFS4VshKbfJDnxrBh2IX919ndi0JO8yoqTRNRNIpavFrZJ9LPVb-FBSfbRY ...

  9. bat批处理重命名问题

    因为要重命名的字符串中有文字,导致重命名出来的文件名都变为乱码了,查理一下需要加两句话 1. @Echo Off Chcp 65001>nul SetLocal EnableDelayedExp ...

随机推荐

  1. Redis笔记4-持久化方案

    一:快照模式 默认redis是会以快照的形式将数据持久化到磁盘的(一个二进制文件,dump.rdb,这个文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之内,redis至少发生M次 ...

  2. Centos定时启动和清除任务

    因为需要定时并发执行任务,所以查到了crontab这个工具,介绍一下其用法: SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=roo ...

  3. 如何更改Ubuntu的root密码

    安装Ubuntu系统时,只提示了设定用户密码,该密码可用于普通用户暂时获取root的权限,执行一些需要root权限的操作,而没有要求我们设置root密码,在需要用到root密码时,却想不起来,很尴尬啊 ...

  4. vscode格式化Vue出现的问题

    一.VSCode中使用vetur插件格式化vue文件时,js代码会自动加上冒号和分号 本来就是简写比较方便舒服,结果一个格式化回到解放前 最后找到问题原因: 首先,vetur默认设置是这个样的.也就是 ...

  5. Java Web项目(Extjs)报错四

    1.Java Web项目(Extjs)报错四 具体报错如下: usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ...

  6. Caused by: The Result type [json] which is defined in the Result annotation on the class

    1.错误描述 严重: Dispatcher initialization failed Unable to load configuration. - [unknown location] at co ...

  7. 多线程下不重复读取SQL Server 表的数据

    在进行一些如发送短信.邮件的业务时,我们经常会使用一个表来存储待发送的数据,由后台多个线程不断的从表中读取待发送的数据进行发送,发送完成后再将数据转移到历史表中,这样保证待发送表的数据一般情况下不会太 ...

  8. Django学习-7-ORM操作

    select * from tb where id > 1    # 对应关系     models.tb.objects.filter(1id__gt=)         models.tb. ...

  9. 21个DOS常用命令

    DOS,可别不知道DOS在哪里运行,有好几种方法1.开始菜单---程序---附件---命令提示符2.开始菜单---运行---打命令CMD 一.常用DOS命令(1)cd..                ...

  10. java实现全排列问题

    1.问题描述: 一组字符串的全排列,按照全排列的顺序输出,并且每行结尾无空格. 2.输入: 输入一个字符串 3.输入示例: 请输入全排列的字符串: abc 4.输出示例: a b c a c b b ...