当前位置:首页 » 《随便一记》 » 正文

⭐️UI自动化控制微信发送或转发图片消息✨_小小明-代码实体的专栏

4 人参与  2021年11月29日 12:43  分类 : 《随便一记》  评论

点击全文阅读


在前面《UI自动化轻松解决微信手工群发消息的烦恼》一文中,我演示了如何使用uiautomation控制微信发送文本消息。

前几天又有群友询问:

image-20210918120410297

虽然之前觉得太简单懒得做,但今天又想起这个问题,考虑到很多网友不知道如何实现,所以今天再简单演示一下。

uiautomation控制微信发送图片

其实原理非常简单,之前无非是将需要发送的文本复制到剪切板再粘贴,那么其实对于图片也一样,我们只需要将需要发送的图片放入剪切板即可,其他地方逻辑都一样。

那么如何将图片放入剪切板呢?

uiautomation已经提供了SetClipboardBitmap方法,实现代码如下:

from uiautomation.uiautomation import Bitmap

auto.SetClipboardBitmap(Bitmap.FromFile(path))

之前我们发送图片消息的完整代码为:

import time
import uiautomation as auto

wechatWindow = auto.WindowControl(
    searchDepth=1, Name="微信", ClassName='WeChatMainWndForPC')
wechatWindow.SetActive()
search = wechatWindow.EditControl(Name='搜索')
edit = wechatWindow.EditControl(Name='输入')
messages = wechatWindow.ListControl(Name='消息')
sendButton = wechatWindow.ButtonControl(Name='发送(S)')


def send2name(name, txt, wait_time=0.1):
    search.Click()
    auto.SetClipboardText(name)
    edit.SendKeys('{Ctrl}v')
    # 等待微信索引搜索跟上
    time.sleep(wait_time)
    search.SendKeys("{Enter}")
    auto.SetClipboardText(txt)
    edit.SendKeys('{Ctrl}v')
    sendButton.Click()
    
name = "小小明"
txt = "小小明你好,收到这条消息说明你的程序已经成功---来自自动化测试程序"
send2name(name, txt)

下面我们改造到支持图片发送:

import time
import uiautomation as auto
from uiautomation.uiautomation import Bitmap

wechatWindow = auto.WindowControl(
    searchDepth=1, Name="微信", ClassName='WeChatMainWndForPC')
wechatWindow.SetActive()
search = wechatWindow.EditControl(Name='搜索')
edit = wechatWindow.EditControl(Name='输入')
messages = wechatWindow.ListControl(Name='消息')
sendButton = wechatWindow.ButtonControl(Name='发送(S)')


def selectSessionFromName(name, wait_time=0.1):
    search.Click()
    auto.SetClipboardText(name)
    edit.SendKeys('{Ctrl}v')
    # 等待微信索引搜索跟上
    time.sleep(wait_time)
    search.SendKeys("{Enter}")


def send_msg(content, msg_type=1):
    if msg_type:
        auto.SetClipboardText(content)
    else:
        auto.SetClipboardBitmap(Bitmap.FromFile(content))
    edit.SendKeys('{Ctrl}v')
    sendButton.Click()

测试一下切换并发送文本消息和图片消息:

name = "小小明"
selectSessionFromName(name)
content = "小小明你好,收到这条消息说明你的程序已经成功---来自自动化测试程序"
send_msg(content)
content = r"C:\Users\ASUS\Pictures\avatar.png"
send_msg(content, msg_type=0)

202109182017

这样,我们就完成了图片消息的发送。

图片消息的转发

上文中,已经实现了转发当前最后一条文本消息的功能,但是假如最后一条消息是图片时,之前的方法就会报错退出。这到底是什么情况呢?我们看看图片与文本消息节点的异同:

image-20210918223943726

为了使代码更加通用,我们必须分析出更通用的规律,发下图可以发现规律:

image-20210918223958402

每一条消息由一个面板的三个子节点组成,首尾两个节点的内容互斥,首节点有按钮表示非本人发送的消息,尾节点有按钮表示自己发送的消息,中间节点是一个包括了消息内容的面板。

那么可以将之前的代码由message.EditControl().RightClick()修改为message.GetFirstChildControl().GetChildren()[1].RightClick()

另外之前的代码可以排除最后一条消息为拍一拍的情况,但实际上最后一条还有可能是撤回,也需要排除。在向前寻找节点时可能碰到时间,也需要排除掉。

对于转发消息,我们基本只需要转发自己发送的消息,下面的代码将再当前窗口中找到,自己发送的最后一条消息,当然需要保证自己最后发送的消息在可视范围内,只要是向文件传输助手发送的消息都不会存在这个问题。

改造之前的消息发送代码,最终如下:

def relay2users(users, max_n=9, wait_time=0.1):
    message = messages.GetLastChildControl()
    while True:
        nodes = message.GetFirstChildControl().GetChildren()
        if nodes and nodes[2].ControlTypeName == "ButtonControl":
            break
        message = message.GetPreviousSiblingControl()
    nodes[1].RightClick()
    menu = wechatWindow.MenuControl()
    menu_items = menu.GetLastChildControl().GetFirstChildControl().GetChildren()
    for menu_item in menu_items:
        if menu_item.ControlTypeName != "MenuItemControl":
            continue
        if menu_item.Name == "转发":
            menu_item.Click()
            break
    send2ps = wechatWindow.WindowControl(Name="转发给", ClassName='SelectContactWnd')
    receiver = send2ps.EditControl(Name="搜索")
    sendB2 = send2ps.ButtonControl(Name='发送')
    items = send2ps.ListControl()
    for i in range(0, len(users), max_n):
        users_split = users[i:i+max_n]
        for user in users_split:
            receiver.Click()
            auto.SetClipboardText(user)
            receiver.SendKeys('{Ctrl}v')
            # 等待UI组件的渲染变化
            time.sleep(wait_time)
            items.ButtonControl().Click()
            receiver.GetParentControl().GetNextSiblingControl().Click()
        sendB2.Click()

下面测试一下转发这条图片消息到指定会话名称:

image-20210918222419518

users = ["文件传输助手", "小小明", "Playmarker",
         "数据分析与商业化设计", "道财Gdc", "云朵君MrCloudData"]
relay2users(users)

202109182235

可以看到这样就实现了图片消息的转发。


点击全文阅读


本文链接:http://zhangshiyu.com/post/31397.html

消息  发送  图片  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1