python办公自动化系列之金蝶K3自动登录(一)
做办公自动化的小伙伴都知道,驱动SAP GUI我们有SAP原生提供的【脚本录制与回放】以及SAP Scripting API可参考;驱动Office Excel等,我们有微软提供的【录制宏】功能;驱动各类浏览器我们有selenium和Katalon Recorder。这些工具都可以提供简易的代码录制功能,稍微有点编程基础的小伙伴可以基于录制后自动生成的代码,整合上业务逻辑,稍加调整,就可以轻松完成一个自动化脚本的开发。
可桌面软件远不止这几大类啊,更不是每个公司都舍得花钱买SAP的ERP产品,比如今天的国产ERP巨头金蝶公司的K3 Wise客户端,我们是否也有类似的办法来自动化呢?小爬这里给出的答案是:可以,但是没有官方提供的【动作录制】功能快速生成脚本,这次真的只能徒手写代码了,除了微软大大提供的Windows系统 API,似乎我们什么都依靠不了。小爬今天就带大家层层分解,用python脚本一步步搞定金蝶K3的UI自动化。

- 自动化启动K3 Wise软件
我们需要判断金蝶K3 Wise是否已经启动,如果没有,则自动化启动它,我们再次请出我们的好帮手SPY++和了不起的Pywin32库。通过SPY++的元素捕获功能拿到K3登录界面的窗口标题(caption)和类名(Class),再用FindWindow函数来捕获即可,最后再决定是否用subprocess库来启动对应的K3 exe文件,这一步的示例代码如下:

1 # 需要提前使用管理员权限运行VScode或者Pycharm,否则无法正常使用
2 import win32gui,win32api,win32con,subprocess,time,os
3 def getK3LoginHwnd():
4 sysLoginWnd=win32gui.FindWindow('ThunderRT6Form',"金蝶K/3系统登录") # K3系统登录窗
5 if sysLoginWnd==0:
6 subprocess.Popen(r'C:\Program Files (x86)\Kingdee\K3ERP\K3MainNet.exe')
7
8 # subprocess发送指令启动后需要等K3登录窗彻底可见后,再进行后续操作
9 while sysLoginWnd==0:
10 time.sleep(0.3)
11 sysLoginWnd=win32gui.FindWindow('ThunderRT6Form',"金蝶K/3系统登录") # K3系统登录窗
12 isSysLoginWndVisible=0
13 while isSysLoginWndVisible==0:
14 time.sleep(0.3)
15 sysLoginWnd=win32gui.FindWindow('ThunderRT6Form',"金蝶K/3系统登录") # K3系统登录窗
16 isSysLoginWndVisible=win32gui.IsWindowVisible(sysLoginWnd) # 判断窗口是否已经对用户可见
17 return sysLoginWnd
需要注意的是,我们需要使用管理员权限打开VScode或者Pycharm后再调试脚本,否则windows提示【请求的操作需要提升】,如下图所示。

- 驱动K3登录窗,成功登录特定账套
1、设置【组织机构】下拉框

大胆猜测,上图中组织机构下拉框ThunderRT6ComboBox是ComboBox的子类,继承了它的很多特性。比如我们希望选择组织机构【01|查询帐套】,它在combobox列表中索引为1。我们先判断当前值是否是我们要的,否则就选择某个下拉选项。示例代码如下:
1 def setOrganization(sysLoginWnd,organizationIndex):
2 '''根据K3登录窗的句柄和下拉框索引值,选择特定的组织机构'''
3 mainHwnd1=win32gui.FindWindowEx(sysLoginWnd,0,None, '') # ThunderRT6PictureBoxDC
4 mainHwnd2=win32gui.FindWindowEx(sysLoginWnd,mainHwnd1,None, '') # ThunderRT6PictureBoxDC
5 organizationHwnd=win32gui.FindWindowEx(mainHwnd2,0,"ThunderRT6ComboBox", '') # 组织机构
6 currentOrgIndex=win32gui.SendMessage(organizationHwnd, win32con.CB_GETCURSEL) # 当前combobox选中的index
7 if currentOrgIndex!=organizationIndex:
8 win32gui.SendMessage(organizationHwnd, win32con.CB_SETCURSEL, organizationIndex, 0)
划重点了,K3登录窗中,【组织机构】和【当前帐套】是二级联动的下拉菜单,而我们上面定义的setOrganization方法一通操作后,只更改了【组织机构】,却无法使得【当前帐套】产生联动,应该是后台的消息机制没能推送给程序,导致无法自动联动,实在是空欢喜。莫慌,小爬这里有锦囊妙计:利用python脚本设置好了【组织机构】下拉框后,再激活【组织机构】下拉框,使其处于蓝底,这个时候模拟键盘↓和键盘↑,来激活【当前帐套】的二级联动效果。对了,这里还需要注意一个坑:临界问题,比如下拉框选中的是最后一项,此时应该模拟的是键盘↑+键盘↓,思路理清后,果断完善上面的setOrganization方法,代码如下:
1 def setOrganization(sysLoginWnd,organizationIndex):
2 '''根据K3登录窗的句柄sysLoginWnd和下拉框索引值organizationIndex,选择特定的组织机构'''
3 mainHwnd1=win32gui.FindWindowEx(sysLoginWnd,0,None, '') # ThunderRT6PictureBoxDC
4 mainHwnd2=win32gui.FindWindowEx(sysLoginWnd,mainHwnd1,None, '') # ThunderRT6PictureBoxDC
5 organizationHwnd=win32gui.FindWindowEx(mainHwnd2,0,"ThunderRT6ComboBox", '') # 组织机构
6 currentOrgIndex=win32gui.SendMessage(organizationHwnd, win32con.CB_GETCURSEL) # 当前combobox选中的index
7 if currentOrgIndex!=organizationIndex:
8 win32gui.SendMessage(organizationHwnd, win32con.CB_SETCURSEL, organizationIndex, 0)
9
10 '''模拟鼠标左键点击元素,激活它'''
11 win32gui.SendMessage(organizationHwnd, win32con.WM_LBUTTONDOWN, 0, 0)
12 time.sleep(0.01)
13 win32gui.SendMessage(organizationHwnd, win32con.WM_LBUTTONUP, 0, 0)
14
15 '''小爬此处的场景中,【组织机构】有6个下拉项,那么最大的index就是5'''
16 if organizationIndex<5: # 模拟键盘↓+键盘↑
17 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_DOWN, 0)
18 time.sleep(0.01)
19 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_DOWN, 0)
20 time.sleep(0.1)
21 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_UP, 0)
22 time.sleep(0.01)
23 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_UP, 0)
24 else: # 模拟键盘↑+键盘↓
25 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_UP, 0)
26 time.sleep(0.01)
27 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_UP, 0)
28 time.sleep(0.1)
29 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYDOWN, win32con.VK_DOWN, 0)
30 time.sleep(0.01)
31 win32gui.PostMessage(organizationHwnd, win32con.WM_KEYUP, win32con.VK_DOWN, 0)
32 time.sleep(0.1)
今天的分享就到这里了,后续小爬会教大家如何驱动剩下的K3登录界面控件,实现自动登录账套,自动切换账套,玩转金蝶K3的UI自动化。
欢迎扫码关注我的公众号 获取更多爬虫、数据分析的知识!

python办公自动化系列之金蝶K3自动登录(一)的更多相关文章
- python办公自动化系列之金蝶K3自动登录(二)
接上一篇博文python办公自动化系列之金蝶K3自动登录(一),我们接着聊聊利用python脚本实现金蝶K3 Wise客户端自动登录这一需求. 如上图所示,自动选择[组织机构]后,我们还需要驱动[当前 ...
- python办公自动化系列之金蝶K3(三)
小爬在之前的两篇文章 [python办公自动化系列之金蝶K3自动登录(一)].[python办公自动化系列之金蝶K3自动登录(二)]带大家系统搞定了K3客户端的自动登录难题,但是搞定[自动登录]只是我 ...
- python网络爬虫之使用scrapy自动登录网站
前面曾经介绍过requests实现自动登录的方法.这里介绍下使用scrapy如何实现自动登录.还是以csdn网站为例. Scrapy使用FormRequest来登录并递交数据给服务器.只是带有额外的f ...
- python带cookie提交表单自动登录(转)
今天突然把博客给申请了,以前也想过的,奈于自己觉得水平还太低有点不好意思写博客,但是后来一想,自己的记录所学,加深印象,主要还是为了学习进步,不怕丢人!今天就稍微回顾一下这两天写的一段用python模 ...
- 使用Python定时执行一任务,自动登录某web系统,生成报表,然后发送邮件给指定人员
一.项目需求 每周从A系统生成一张Excel报表,发送此报表给指定人员,相关人员依据此报表去完成后续的工作. 项目限制: 1.无法通过EDI系统交互的方式从后台读取数据 2.由于公司网络环境限制,不能 ...
- python带cookie提交表单自动登录
import urllib import urllib2 import cookielib login_url = "xxxxxxxxxxxxx" cj = cookielib.C ...
- [Python爬虫] Selenium实现自动登录163邮箱和Locating Elements介绍
前三篇文章介绍了安装过程和通过Selenium实现访问Firefox浏览器并自动搜索"Eastmount"关键字及截图的功能.而这篇文章主要简单介绍如何实现自动登录163邮箱,同时 ...
- Python实现BBS自动登录并发帖
初学Python有了一段时间,寒假里又看了一些Web编程方面的知识,就写了一个实现bbs自动登录和发帖的Python脚本 由于本人学校BBS站首页使用js加载,貌似通过首页登录不大可行,然后就分析表单 ...
- 金蝶K3 WISE 快速登录
金蝶K3 WISE 快速登录 "C:\Program Files (x86)\Kingdee\K3ERP\k3main.exe" -LoginUser|账套号|账套密码|用户账号| ...
随机推荐
- 【嵌入式AI】全志 XR806 say hello world
欢迎关注我的公众号 [极智视界],回复001获取Google编程规范 O_o >_< o_O O_o ~_~ o_O 大家好,我是极智视界,本文介绍了全志 ...
- python-mysql-replication原理分析
源码地址:https://github.com/noplay/python-mysql-replication 文件解析: ├── binlogstream.py ├── bitmap.py ├── ...
- ON LARGE BATCH TRAINING FOR DEEP LEARNING: GENERALIZATION GAP AND SHARP MINIMA
目录 概 主要内容 一些解决办法 Keskar N S, Mudigere D, Nocedal J, et al. On Large-Batch Training for Deep Learning ...
- nginx -g "daemon off;" 你学废了吗?
去年的时候写了一篇原创<前后端分离,如何在前端项目中动态插入后端API基地址?(in docker)>, 我自认为这篇生产实践是对大前端. 容器化.CI/CD的得意之作. 对于前后端分离的 ...
- MySQL入门安装,及环境配置,初始化教程
一.MySQL安装(win64) 免费的社区版下载地址:https://dev.mysql.com/downloads/mysql 接着会跳到这个页面 下载完后,我们将 zip 包解压到相应的目录,这 ...
- Java访问Elasticsearch报错Request cannot be executed; I/O reactor status: STOPPED
简介 使用ES过程中遇到一个Request cannot be executed; I/O reactor status: STOPPED 的异常,大概意思是和server端的连接异常终止了.开始以为 ...
- Python升级至2.7方法
在Linux下Python升级至2.7的详细步骤方法, 此处的升级,使用的是全新安装新版本,替换旧版本的方法, 同时新旧版本可以共存,将默认python指向最新2.7版本即可. 1.下载Python- ...
- SpringBoot 之 静态资源路径、显示首页、错误页
静态资源路径 静态资源支持放在以下路径中,访问优先级从上到下: classpath:/META-INF/resources/ classpath:/resources/ classpath:/stat ...
- pymysql防止SQL注入的方法
import pymysql class Db(object): def __init__(self): self.conn = pymysql.connect(host="192.168. ...
- linux修改默认的SSH远程端口22
1.编辑sshd_config文件 [root@localhost ~]# vim /etc/ssh/sshd_config 搜索 #Port 22行,删除开头的 # 字符,然后将其替换为要使用的端 ...