> 文档中心 > 在学uiautomation(以微信进入青年大学习为例)

在学uiautomation(以微信进入青年大学习为例)

目录

一、前言

二、前期准备

三、开干

3.1打开微信客户端

3.2判断微信是否登录 

3.3微信页面操作

3.4具体页面操作 

3.5对产生的新窗格进行操作

3.6页面关闭

3.7全部代码展示 

四、总结


一、前言

        之前笔者写过关于uiautomation的一篇入门级文章初识UI自动化(inspect.exe + uiautomation)https://blog.csdn.net/knighthood2001/article/details/124297008?spm=1001.2014.3001.5502不过没有给出相应的学习例子,因此本篇文章主要以微信的青年大学习为例。教你如何使用uiautomation进入微信青年大学习。

二、前期准备

2.1模块准备

import subprocessimport uiautomation as autoimport time

        ①subprocess模块用来启动微信客户端

        ②uiautomation模块用来UI自动化 

2.2软件准备

        inspect.exe(或者其他用于获取窗口或控制句柄的软件,如UISpy.exe)

三、开干

        如上图,首先我们需要知道,青年大学习的很多页面是只能在微信客户端中才能打开。因此我们采取uiautomation模块进行模仿人进行手动操作。


3.1打开微信客户端

# 可执行文件的具体地址信息subprocess.Popen('E:\微信\WeChat\WeChat.exe')

使用subprocess.Popen('微信具体地址')打开微信客户端


3.2判断微信是否登录 

“微信”窗格页面 

“进入微信”按钮页面 

代码如下: 

# 判断微信是否已经登录wechat_login = auto.PaneControl(Name='微信')enter_wechat_btn = wechat_login.ButtonControl(Name='进入微信')if enter_wechat_btn.Exists():    enter_wechat_btn.Click()

        上图可以看出,“进入微信”按钮是“微信”窗格的子控件。因此我们可以先定位“微信”窗格,然后再定位“进入微信”按钮。定位方式可以通过具体控件的类型、名字等来定位。

        然后通过Exists()函数来判断控件是否存在,存在则进行点击事件。

注意:“微信”窗格页面中的控件类型为PaneControl,并给出了ClassName,不过auto.PaneControl()中没有ClassName这一参数。


3.3微信页面操作

        登录微信后,“微信”窗口页面的相关句柄如下。

# 进入微信后wechatWindow = auto.WindowControl(searchDepth=1, className='WeChatMainWndForPC', Name='微信')

# 点击聊天button = wechatWindow.ButtonControl(Name='聊天')button.Click()# 搜索search = wechatWindow.EditControl(Name='搜索')search.Click()

  

        接下来在搜索框中搜索青春浙江,然后在结果中遍历,判断名字是否为青春浙江,如果是则点击

# 输入查找内容search.GetParentControl().GetChildren()[1].SendKeys('青春浙江')searResult = wechatWindow.ListControl(Name='搜索结果').GetChildren()for sear in searResult:    # print(sear.Name)    if sear.Name == '青春浙江': sear.Click() break

不过还有一种方法,即输入青春浙江,然后回车

# 通过回车search.GetParentControl().GetChildren()[1].SendKeys('青春浙江')time.sleep(2)wechatWindow.SendKeys('{Enter}')

注意:

输入青春浙江后,需要一点时间然后再回车,不然结果不正确。笔者认为是只要运行了第一行代码,即使内容还没输完,就运行了回车的代码。

SendKeys('文本或者按键')不仅仅支持文本的输入,也支持按键的使用,包括组合键的使用。 

例:{Enter}表示回车、{Delete}表示Delete、{Ctrl}v表示Ctrl+v。


3.4具体页面操作 

 

接下来点击更多,然后点击发消息,最后点击大学习。 

session = wechatWindow.PaneControl(Name='会话列表')more = session.ButtonControl(Name='更多')more.Click()send_message = auto.MenuItemControl(Name='发消息')send_message.Click()dxx_btn = session.ButtonControl(Name='大学习')dxx_btn.Click()

3.5对产生的新窗格进行操作

注意:“微信”窗口控件的ClassName与之前的已经发生了更改,因此需要重新定义一个。 

wechatWindow_2 = auto.WindowControl(searchDepth=1, className='CefWebViewWnd', Name='微信')

由于每隔一段时间(如每隔一天)会出现授权信息,需要同意,因此同样需要判断该控件是否存在

# 这个判断会花费较长时间# 每隔一段时间后会出现授权信息agree_btn = wechatWindow_2.ButtonControl(Name="同意")if agree_btn.Exists():    agree_btn.Click()

        接下来就是点击“立即学习”按钮。不过首先得判断一下页面是否为最大化,如果页面处于最大化,会找不到“立即学习”按钮,因此需要点击向下还原。

max = wechatWindow_2.ButtonControl(Name='向下还原')# 判断页面是否最大化if max.Exists():    max.Click()study_icon = wechatWindow_2.ImageControl(Name='立即学习')study_icon.Click()

由于“立即参与”(如上图)是一张没有Name的图片,因此我们可以通过其所在树的位置进行查找。

同理,之后出现的“去学习”也是一张没有Name的图片,也可以通过其所在树的位置进行查找。

# 到达立即参与界面participate_in_btn = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[4].GetChildren()[0]participate_in_btn.Click()# # 到达去学习界面study_page = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[3].GetChildren()[0]time.sleep(5)study_btn = study_page.GetChildren()[9]study_btn.Click()

点击立即参与后,就来到了具体需要学习的页面,为了显示完全,然后获取相应的网址。因此首先进行了最大化页面的操作,然后使用CaptureToImane("图片名字",x,y,长,宽)截取二维码图片并保存,便于后续操作。 

'''1'''# 最大化# 最大化界面有漏洞,最大化后,右上角的图标仍为最大化,而不是向下还原wechatWindow_2.Maximize()time.sleep(2)# 截取二维码图片wechatWindow_2.CaptureToImage('url.jpg', 1218, 257, 190, 185)wechatWindow_2.DoubleClick(960, 10)

注意:经过笔者测试,发现Maximize()函数有漏洞,即使用该方法最大化后,右上角的图标仍显示最大化而不是向下还原,因此笔者最终选择双击窗口最上方进行向下还原操作。


不过,随着对inspect.exe的逐渐熟悉,找到了最大化、向下还原按钮所在树中的位置。因此对以上代码做出了相应的调整,弃用了Maximize()

'''2'''# 最大化# max_page = wechatWindow_2.ButtonControl(Name='最大化')# max_page.Click()# time.sleep(2)# # 截图二维码# wechatWindow_2.CaptureToImage('url.jpg', 1218, 257, 190, 185)# # 向下还原# restore_page = wechatWindow_2.ButtonControl(Name='向下还原')# restore_page.Click()

再深入研究后,发现了更好的获取网址的方法。

首先也是最大化页面,然后用inspect.exe找到网址所在树的位置。

由于网址所在的是编辑控件,查看网址所在区域,虽然没有Name,但是我们发现LegacyIAccessible.Value:    "https://h5.cyol.com/special/daxuexi/cod4a2tb5v/index.html"
中的是网址,所以我们可以通过一些办法找到该网址。

'''3'''max_page = wechatWindow_2.ButtonControl(Name='最大化')max_page.Click()time.sleep(2)edit = wechatWindow_2.EditControl(searchDepth=5).GetValuePattern().Valueprint(edit)# 向下还原restore_page = wechatWindow_2.ButtonControl(Name='向下还原')restore_page.Click()

3.6页面关闭

最后就将页面关闭和微信关闭即可。 

注意:两个控件的ClassName不同,在定义时分开定义了。

# 关闭具体页面wechatWindow_2.ButtonControl(Name='关闭').Click()# 关闭微信界面wechatWindow.ButtonControl(Name='关闭').Click()

3.7全部代码展示 

import subprocessimport uiautomation as autoimport time'''searchFromControl: `Control` or its subclass, if it is None, search from root control(Desktop).searchDepth: int, max search depth from searchFromControl.Depth: int, only search controls in relative depth from searchFromControl, ignore controls in depth(0~Depth-1),    if set, searchDepth will be set to Depth too.'''# 可执行文件的具体地址信息subprocess.Popen('E:\微信\WeChat\WeChat.exe')# 判断微信是否已经登录wechat_login = auto.PaneControl(Name='微信')enter_wechat_btn = wechat_login.ButtonControl(Name='进入微信')if enter_wechat_btn.Exists():    enter_wechat_btn.Click()# 进入微信后wechatWindow = auto.WindowControl(searchDepth=1, className='WeChatMainWndForPC', Name='微信')# 点击聊天button = wechatWindow.ButtonControl(Name='聊天')button.Click()# 搜索search = wechatWindow.EditControl(Name='搜索')search.Click()# 通过回车search.GetParentControl().GetChildren()[1].SendKeys('青春浙江')time.sleep(2)wechatWindow.SendKeys('{Enter}')session = wechatWindow.PaneControl(Name='会话列表')more = session.ButtonControl(Name='更多')more.Click()send_message = auto.MenuItemControl(Name='发消息')send_message.Click()dxx_btn = session.ButtonControl(Name='大学习')dxx_btn.Click()# ---------------------------------------------wechatWindow_2 = auto.WindowControl(searchDepth=1, className='CefWebViewWnd', Name='微信')# 这个判断会花费较长时间# 每隔一段时间后会出现授权信息agree_btn = wechatWindow_2.ButtonControl(Name="同意")if agree_btn.Exists():    agree_btn.Click()max = wechatWindow_2.ButtonControl(Name='向下还原')# 判断页面是否最大化if max.Exists():    max.Click()study_icon = wechatWindow_2.ImageControl(Name='立即学习')study_icon.Click()# 到达立即参与界面participate_in_btn = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[4].GetChildren()[0]participate_in_btn.Click()# # 到达去学习界面study_page = wechatWindow_2.DocumentControl(Name="青春浙江“青年大学习”").GetChildren()[0].GetChildren()[3].GetChildren()[0]time.sleep(5)study_btn = study_page.GetChildren()[9]study_btn.Click()'''3'''# 最大化max_page = wechatWindow_2.ButtonControl(Name='最大化')max_page.Click()time.sleep(2)# 获取网址edit = wechatWindow_2.EditControl(searchDepth=5).GetValuePattern().Valueprint(edit)# 向下还原restore_page = wechatWindow_2.ButtonControl(Name='向下还原')restore_page.Click()# 关闭具体页面wechatWindow_2.ButtonControl(Name='关闭').Click()# 关闭微信界面wechatWindow.ButtonControl(Name='关闭').Click()

四、总结

        ①微信进入青年大学习的方式有很多,上述讲的只是其中一种方法,之后笔者也会更新其他的方法。

        ②代码总是在不断的改善,只要你多思考。由于笔者知识有限,上述过程中存在许多地方可以改善。例如,判断某个控件是否存在,如果该控件不存在,将会花费很长的时间去寻找判断,这是一处地方可以进行改善。又如,笔者不太懂SearchDepthDepth的具体用法,虽然之前也有讲过。

        ③上述内容如有错误,请指正!!

天天排行榜