今天下载了一个英文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. tcp/ip 卷一 读书笔记(1)tcp/ip 概述

    TCP/IP协议概述 术语 广域网 WAN 局域网 LAN TCP/IP四层网络模型 TCP/IP通常被认为是一个四层协议系统 网络接口层 包括arp,rarp协议,包括操作系统中的网卡驱动程序和对应 ...

  2. yum仓库详细解读

    Yum:Yellowdog Updater,Modified的简称,起初由yellow dog发行版的开发者Terra Soft研发,用Python编写,后经杜克大学的Linux@Duke开发团队进行 ...

  3. jenkins+ant+jmeter自动化环境搭建(一)

                        写在最前面: jmeter:测试接口的工具,支持java语言: ant:Apache Ant是一个Java库和命令行工具,其任务是将构建文件中描述的进程作为相互 ...

  4. 2.4 PCI总线的配置

    PCI总线定义了两类配置请求,一个是Type 00h配置请求,另一个是Type 01h配置请求.PCI总线使用这些配置请求访问PCI总线树上的设备配置空间,包括PCI桥和PCI Agent设备的配置空 ...

  5. zTree实现地市县三级级联Service接口

    zTree实现地市县三级级联Service接口 ProvinceService.java: /** * @Title:ProvinceService.java * @Package:com.gwtjs ...

  6. freemarker报错之十一

    1.错误描述 六月 03, 2014 11:00:35 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Template proc ...

  7. HighCharts基本折线图

    1.设计源码 <!DOCTYPE html> <!-- To change this license header, choose License Headers in Projec ...

  8. pat1111-1120

    1111 比较麻烦的最短路 #include<cmath> #include<map> #include<iostream> #include<cstring ...

  9. WPF自学入门(二)WPF-XAML布局控件

    上一篇介绍了xaml基本知识,我们已经知道了WPF简单的语法.那么接下来,我们要认识一下WPF的布局容器.布局容器可以使控件按照分类显示,我们一起来看看WPF里面可以使用哪些布局容器用来布局. 在WP ...

  10. span是没有value标签的,要向获得标签内部的值改怎么办。

    1,js实现 var div = document.getElementById('divId');var spans = div.getElementsByTagName('span');var s ...