最近在给朋友做个工作用的软件,需要和微信配套使用且需要实现一些自动操作。
- 通过好友请求并随机备注。
- 根据关键字自动回复,包括文字、图片及文件。
- 定时发送信息,包括单次、隔日、每周末及每日。
- 处理转账,根据金额及备注进行相应操作,包括接收转账后一系列操作或退回转账。
- 处理扫码付款,同上一条相类似。
- 手动批量发送信息
- 保存所有好友信息
上诉功能可以很容易实现,但是还存在几个不足点,例如
- 不能够后台操作,也就是说微信在工作期间,在一些操作过程中,电脑不能正常使用,其他时间无影响。针对这个情况,有一个解决方案,即将任务设置放在本地,将微信放在服务器,天翼云的低配虚拟主机,八十元/年。
- 处理转账较慢,大概最短需要3秒,最长需要5秒。这一过程暂时没有找到更合适的解决办法。
以上就是本篇文章的简要介绍,下面来具体谈一谈。
目录
- 1. 工具说明
-
- 1.1 微信版本
- 1.2 python 版本
- 2. 总览
-
- 2.1 好友信息列表
- 2.2 自动回复设置
- 2.3 好友转账及二维码付款
- 2.4 定时信息
- 3. 实现过程
-
- 3.1 获取微信PID
- 3.2 获取好友信息
- 3.3 包装点击控件
- 3.4 获取信息列表
- 3.5 点击或搜索好友
- 3.6 删除好友聊天框
- 3.7 通过好友申请
- 3.8 修改用户名
- 3.9 发送文本信息
- 3.10 发送图片
- 3.11 处理转账
- 3.12 确认收款及退回
- 4. 总说明
1. 工具说明
1.1 微信版本
我一直使用的是2.9.5版本。最新版本和更旧的版本我都使用过,在所有可用的版本中,这个版本是运行最合适的一个版本,旧版本有些功能不全,而最新版本过于臃肿,所以建议找到这个版本使用。
1.2 python 版本
我是用的是 python3.5,在 pycharm 中建立虚拟环境,对于库包,随用随装。
2. 总览
设置端是按照朋友需求写的,方法都是写好的,直接调用就可以。设置端可以根据自己的需求写。在此我只是介绍一下代码能够实现的功能。
2.1 好友信息列表
2.2 自动回复设置
2.3 好友转账及二维码付款
2.4 定时信息
3. 实现过程
from pywinauto.application import Application
class WeChat:
PID = get_pid()
if not self.PID:
print('未检测到微信运行')
return 0
else:
# 在这里要设置应用后端,即 uia 或 win32,这里微信要设置为 uia,具体方法可参考文末链接
self.app = Application(backend='uia')
self.app.connect(process=self.PID)
self.win = self.app[u'微信']
print('已建立与微信链接')
整个包装成类,方便在写设置端的时候直接继承,方便使用
3.1 获取微信PID
from psutil import process_iter
def get_pid(self):
PID = process_iter()
for pid_temp in PID :
pid_dic = pid_temp .as_dict(attrs=['pid','name'])
if pid_dic['name'] == 'WeChat.exe':
return pid_dic['pid']
else:
return 0
3.2 获取好友信息
def get_text(self):
try:
# 在这里如此定位控件是最快的,逐级定位思路清晰,定位精准
return self.win.child_window(title="消息", control_type="List").child_window(control_type="Edit", found_index=0).window_text()
except:
return ''
3.3 包装点击控件
from pywinauto import mouse
# 左键点击某个控件
def click_one(self, title='', control_type='', button='left', found_index=0, left=10, top=10, times=1):
""" :param title: 控件名称 :param control_type: 控件类型 :param button: left right middle 对应左、右、中三个键 :param times: 点击次数 :param found_index: 选择同名同类型多个控件中的第几个 :param left: X 正方向修正 :param top: Y 正方向修正 :return: """
# 在这里控件名称和类型,可以只选择一个,不过定位精准度不高
if title == '' and control_type == '':
raise ValueError('控件名和控件类型不可为空!')
position = self.win.child_window(title=title, control_type=control_type, found_index=found_index).rectangle()
for i in range(times):
mouse.click(button=button, coords=(position.left + left, position.top + top))
if times > 1:
sleep(0.2)
3.4 获取信息列表
def get_users(self):
user_lis = []
try:
# 列表中添加的是发来新信息的好友名称
users = self.win.child_window(title="会话", control_type="List").children()
for user in users:
user_lis.append(user.window_text())
except:
print('获取好友列表失败')
pass
return user_lis
3.5 点击或搜索好友
# user 为需要找到的好友名称,如果信息列表中存在,则直接点击,不存在则搜索
def find_user(self, user=''):
if user== '':
raise ValueError('好友名称不可为空!')
if self.win.child_window(title=user, control_type='Text').exists(timeout=0.2):
self.click_one(title=user, control_type='Text')
else:
self.click_one(title='搜索', control_type='Edit', times=2)
# 这里必须要等待一定时间,等待搜索框加载出来,时间可以自行尝试着缩短
sleep(0.5)
self.win.type_keys(user)
sleep(0.5)
self.win.type_keys('{ENTER}')
self.click_one(title='输入', control_type='Edit')
定位到好友有两种情况,第一种是存在于聊天界面中,第二种是不在聊天列表中,所以为了方便,先判断好友是否在当前聊天框中,如果没有,再搜索,毕竟搜索有些浪费时间
3.6 删除好友聊天框
def delete_user(self, user=''):
try:
self.click_one(title=user, control_type='Text', button='right')
# 这里我提供了两种删除聊天的方式,速度两者相差无几
self.app.PopupMenu['删除聊天'].click_input('left')
# self.app['Menu'].child_window(title='删除聊天', control_type='Text').click_input('left')
except:
return None
3.7 通过好友申请
from pyautogui import hotkey
from pywinauto import mouse
# 添加指定好友有瑕疵,名称仅限字母、汉字、一般符号
def add_new_amigo(self, user=''):
self.click_one(title='通讯录', control_type='Button')
self.click_one(title='新的朋友', control_type='ListItem')
hotkey('down')
hotkey('up')
# 这里定位有一些烦琐,我尝试了较为简便的代码,但是速度都没这样繁琐的快,这里就不张贴其他方法了
address_list = self.win.child_window(title=user, control_type="Text").parent().parent().parent().children()[2]
cords = address_list.rectangle()
mouse.click(button='left', coords=(cords.left + 10, cords.top + 10))
hotkey('esc')
hotkey('esc')
self.click_one(title='通讯录', control_type='Button')
3.8 修改用户名
# 修改用户姓名
def fix_user(self, old_name='', new_name=''):
self.find_user(user=old_name)
remark = self.win.child_window(title="备 注", control_type="Text").parent().children()[1]
remark.type_keys(new_name)
3.9 发送文本信息
from pyperclip import copy
from pyautogui import hotkey
def send_message_to_user(self, user='', text=''):
self.find_user(user)
copy(text.replace('|', '\n').strip())
hotkey('ctrl', 'v')
hotkey('enter')
发送文本这里建议不要使用 pywinauto 自有的 type_keys() 方法,使用这一方法会无法保证缩进格式,我尝试过以 type_keys() 为前提的多种方式来保证缩进,但是效果都不太明显,所以说我采用了粘贴的方法,即代码中的 copy() 方法
3.10 发送图片
import win32clipboard as clip
from win32con import CF_DIB
from io import BytesIO
from PIL import Image
from pyautogui import hotkey
def send_image_to_user(self, user='', image_path=''):
self.find_user(user=user)
img = Image.open(image_path)
output = BytesIO()
img.convert("RGB").save(output, "BMP")
data = output.getvalue()[14:]
output.close()
clip.OpenClipboard()
clip.EmptyClipboard()
clip.SetClipboardData(CF_DIB, data)
clip.CloseClipboard()
sleep(0.5)
hotkey('ctrl', 'v')
hotkey('enter')
remove(image_path)
发送图片较为繁琐,如果是采用微信带的发送文件功能,那样速度就慢了很多,所以就将图片储存到剪切板中,再粘贴到聊天框中,以此加快速度。同样,发送文件也是这样的思路,不过发送文件需要先判断一下文件是否在100MB内,因为微信发送文件有大小限制。
3.11 处理转账
def payment_values(self):
if not self.win.child_window(title="微信转账", control_type="Text", found_index=0).exists(timeout=0.1):
if not self.win.child_window(title="微信转账", control_type="ListItem", found_index=0).exists(timeout=0.1):
return 0
# 获取转账备注, 见下方注释1
remark = self.win.child_window(title="微信转账", control_type="Text", found_index=0).parent().parent().children()[0].children()[1].children()[0].window_text()
# 获取转账的金额,只取整数
money = self.win.child_window(title="微信转账", control_type="Text", found_index=0).parent().parent().children()[0].children()[1].children()[1].window_text()
money = int(float(money.replace('¥', '')))
return {
'remark': remark, 'money': money}
- 因为要获取转账备注,所以说定位方式看着很繁琐。如果不需要对方转账填写备注内容,则定位就很简单,只需要定位到 title = ‘确认收款’ 就可以。
3.12 确认收款及退回
from pyautogui import hotkey
#收钱, 收成功 1, 失败 0
def payment_receive(self):
# 在这里之所以要遍历寻找控件,是因为转账这一项,在不同版本微信中有不一样的控件类型,这我已经试验过数个版本
for control_type in ['Text', 'ListItem']:
if self.win.child_window(title="微信转账", control_type=control_type, found_index=0).exists(timeout=0.1):
self.click_one(title='微信转账', control_type=control_type, times=2)
self.click_one(title='确认收钱', control_type='Button')
if self.win.child_window(title="已收钱", control_type="Text", found_index=0).exists(timeout=5):
hotkey('esc')
return 1
else:
return 0
else:
return 0
# 退钱, 退成功 1, 失败 0
def payment_refuse(self):
for control_type in ['Text', 'ListItem']:
if self.win.child_window(title="微信转账", control_type=control_type, found_index=0).exists(timeout=0.1):
self.click_one(title='微信转账', control_type=control_type)
self.click_one(title='立即退还', control_type='Button')
self.click_one(title='退还', control_type='Button')
hotkey('esc')
return 1
else:
return 0
4. 总说明
上述代码块就是实现文章开头功能的相应代码,为了解释方便,我把代码拆分开来加上注释。当然,每个功能模块都有不太合适的地方,只是提供了一个较为方便的思路,对于控制微信,还有其他更为先进的方法,比如说很热门的 hook,这个就相对高深了,有兴趣的可以自己尝试了解一下。
今天的文章python pywinauto 自动控制微信, 关键字回复、收款、定时任务, 代替人工成为微信客服分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/40103.html