当前位置: 首页 > 工具软件 > pywinauto > 使用案例 >

用pywinauto抓取微信公众号

奚光霁
2023-12-01

本文内容在于讨论用pywinauto 如何获取微信控件的问题,欢迎各位大牛指点迷津。

1 pywinauto

pywinauto是个在PC端可以使用的自动化测试框架,感谢作者提供这么好的框架。

其中个人认为非常重要的一个函数就是print_control_identifiers(), 用来打印窗口的控件列表,打印【记事本】可以看到很多控件,知道了控件pid我们就可以采用pywinauto的属性方式操作它,真是帅呆了。

先玩一个【记事本】操作

由于涉及属性【中文】问题,只能采用键值对方式控制控件,这个请注意。

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# @smartcat01
# 自动化notepad

from pywinauto.application import Application
import psutil

# 通过程序名称获取第一个进程ID
def get_pid(name):
    '''
     作用:根据进程名获取进程pid
     返回:返回匹配第一个进程的pid
    '''
    pids = psutil.process_iter()
    for pid in pids:
        if(pid.name() == name):
            return pid.pid
    return 0

# 循环打印菜单
def list_menu(menu_item, space):
    '''
     作用:递归法遍历菜单 
    '''
    for i in menu_item.items():
        if(len(i.text()) > 0):
            print(space + i.text())
        if(i.sub_menu() != None):
            list_menu(i.sub_menu(), "    " + space)


if __name__ == "__main__":

    # 1 链接道程序
    pid = get_pid("notepad.exe")
    if pid > 0:
        #  通过进程号获取已经打开的程序
        app = Application().connect(process = pid)
    else:
        # 如果没有你需要的进程,我们就打开一个新的进程
        app = Application(backend="uia")
        app.start(r"notepad.exe")
    
    # 2 找到记事本主窗口
    win = app.window(title_re = ".*记事本*.")

    # 2.1 打印主窗口控件列表,然后你可以通过控件id操作这个对象
    win.print_control_identifiers();
    print('-----------------')
    # 3 如何文字,对对话框的Edit控件进行操作
    win.Edit.type_keys('@smartcat01',with_spaces=True)
    # 4 打印全部菜单
    list_menu(win.menu(), "")
    # 4.1 点击菜单
    win.menu_select("文件->页面设置")
    
    # 4.1 点击菜单
    #win.menu_select("帮助->关于记事本")
    # 选择全部内容,然后删除
    #win.Edit.select().type_keys('{DELETE}')
    # 5 执行多次换行操作,模拟键盘输入
     win.Edit.type_keys('@smartcat01') 
    win.Edit.type_keys('@smartcat01') 
    win.Edit.type_keys('@smartcat01') 
    win.Edit.type_keys('{ENTER}') 
    win.Edit.type_keys('{ENTER}') 
    # 返回文本框 win.Edit.Texts()
    print(win.Edit.Texts())

但是如果你操作PC端【微信】,你就惨了。

我已经确信,【微信】控件采用了某种方法屏蔽了,我不知道如何才能获取这些控件,然后操作它?

我的微信是新版本 3.6.0.18

如果你知道欢迎一起讨论。

2 定位窗口控件方法

我原来是这么书写的(如下),但是你回报错,原因就是找不到控件

我确信一下方法没有问题,pywinauto 的文档就这么写的,网络上各种文章也都是这么写的,但是你不会活动你想要的结果。

    def get_search_btn(self,user):
  	    btn= self.win.child_window(title="搜索", control_type="Edite")    
     	return btn

以上代码失败了,没有找到控件,但是通过inspect 可以查询到了,我就是奇怪了

3 如何获取微信控件列表呢

我不知道,如果你知道请告诉一下,

感谢阅读;

下面是我采用鼠标模拟方式,进行查询控件,但是这个方法太不好了,类似按键精灵了;

我放弃了其它功能开发,

也许我会采用代理模式+按键精灵去完成这个项目了,但是总感觉很遗憾!

感谢阅读;

4 以下是我用鼠标模拟方式操作

以下代码傻透了,傻透了,我都不想看它,
但是有什么更好的方式呢?

欢迎一起讨论。

感谢!

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# @smartcat01
# pywinauto WindowSpecification

from pywinauto.application import Application
from pywinauto import mouse
from pywinauto.keyboard import send_keys
from pyautogui import hotkey
from pyperclip import copy
import psutil
import time
# 一个微信类的简单操作
class Weixin(object):
    # 1初始化
    def __init__(self):
        # 启动
        # 1 链接道程序
        pid = self.get_pid("WeChat.exe")
        if pid >0 :
            self.app = Application().connect(process = self.get_pid("WeChat.exe"))
        else:
            self.app = Application(backend="uia").start(r"WeChat.exe")
        # 2 获取一个窗口
        self.win = self.app.window(class_name='WeChatMainWndForPC')
        self.win.draw_outline(colour = 'red')
    
    # 定位到查询框,
    @staticmethod
    def get_search_btn(left,top,user):
        mouse.move((left, top))
        mouse.click(coords=(left, top))
        print(left,top)
        send_keys("^a")
        send_keys("{BACKSPACE}")
        send_keys(user)
        time.sleep(2)
        return False

    @staticmethod
    def double_click(left,top):
        mouse.move((left, top))
        mouse.double_click(coords=(left, top))
        time.sleep(2)
        return False
    # 移动窗体
    def move_window(self):
        self.win.move_window(0, 0, width=1000,height=500)
        self.win.set_focus()
        self.win.print_control_identifiers()
    
    
if __name__ == "__main__":

    wx = Weixin()
    wx.move_window()#移动微信到左上角
    wx.get_search_btn(110,41,"阿里云")#采用鼠标定位
    wx.double_click(86,100)#找到这个公众号,我就双击一下
    btn = wx.win.child_window(title=u"订阅号")#这个方法失败了
    print(btn.dump_tree())
 类似资料: