Python实现微信发送文件实例

您所在的位置:网站首页 手机excel怎么发送给微信好友 Python实现微信发送文件实例

Python实现微信发送文件实例

2024-07-03 15:54| 来源: 网络整理| 查看: 265

新建Python文件:wx_file.py,代码如下

# -*- coding: utf-8 -*- # @Author : CxiuM # @Time : 2023-07-06 10:12 # @Name : wx_operation.py """微信群发消息""" import os import time import subprocess import requests import uiautomation as auto from copy import deepcopy from typing import Iterable class WxOperation: """ 微信群发消息的类。 ... Attributes: ---------- wx_window: auto.WindowControl 微信控制窗口 input_edit: wx_window.EditControl 聊天界面输入框编辑控制窗口 search_edit: wx_window.EditControl 搜索输入框编辑控制窗口 Methods: ------- __goto_chat_box(name): 跳转到 指定好友窗口 __send_text(*msgs): 发送文本。 __send_file(*filepath): 发送文件 get_friend_list(tag, num): 可指定tag,获取好友num页的好友数量 send_msg(*names, msgs, file_paths) 单个或批量发送文本和文件 """ def __init__(self): auto.SendKeys(text='{Alt}{Ctrl}z') # 快捷键唤醒微信 self.wx_window = auto.WindowControl(Name='微信', ClassName='WeChatMainWndForPC') assert self.wx_window.Exists(), "窗口不存在" self.input_edit = self.wx_window.EditControl(Name='输入') self.search_edit = self.wx_window.EditControl(Name='搜索') def __goto_chat_box(self, name: str) -> None: """ 跳转到指定 name好友的聊天窗口。 Args: name(str): 必选参数,好友名称 Returns: None """ assert name, "无法跳转到名字为空的聊天窗口" self.wx_window.SendKeys(text='{Ctrl}f', waitTime=0.2) self.wx_window.SendKeys(text='{Ctrl}a', waitTime=0.1) self.wx_window.SendKey(key=auto.SpecialKeyNames['DELETE']) auto.SetClipboardText(text=name) self.wx_window.SendKeys(text='{Ctrl}v', waitTime=0.1) self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=0.2) def __send_text(self, *msgs) -> None: """ 发送文本. Args: *msgs(Iterable or str): 必选参数,为发送的文本 Returns: None """ for msg in msgs: assert msg, "发送的文本内容为空" self.input_edit.SendKeys(text='{Ctrl}a', waitTime=0.1) self.input_edit.SendKey(key=auto.SpecialKeyNames['DELETE']) # self.input_edit.SendKeys(text=msg, waitTime=0.1) # 一个个字符插入,不建议使用该方法 # 设置到剪切板再黏贴到输入框 auto.SetClipboardText(text=msg) self.input_edit.SendKeys(text='{Ctrl}v', waitTime=0.1) self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=0.2) def __send_file(self, *file_paths) -> None: """ 发送文件. Args: *file_paths(Iterable or str): 必选参数,为文件的路径 Returns: None """ all_path = str() for path in file_paths: full_path = os.path.abspath(path=path) assert os.path.exists(full_path), f"{full_path} 文件路径有误" all_path += "'" + full_path + "'," args = ['powershell', f'Get-Item {all_path[:-1]} | Set-Clipboard'] # 去除console 弹窗 startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags = subprocess.CREATE_NEW_CONSOLE | subprocess.STARTF_USESHOWWINDOW startupinfo.wShowWindow = subprocess.SW_HIDE subprocess.Popen(args=args, startupinfo=startupinfo) time.sleep(0.5) self.input_edit.SendKeys(text='{Ctrl}v', waitTime=0.2) self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=0.2) def get_friend_list(self, tag: str = None, num: int = 10) -> list: """ 获取微信好友名称. Args: tag(str): 可选参数,如不指定,则获取所有好友 num(int): 可选参数,如不指定,只获取10页好友 Returns: list """ def click_tag(): """点击标签""" contacts_management_window.ButtonControl(Name="标签").Click() # 点击 通讯录管理 self.wx_window.ButtonControl(Name="通讯录").Click() self.wx_window.ListControl(Name="联系人").ButtonControl(Name="通讯录管理").Click() contacts_management_window = auto.GetForegroundControl() # 切换到通讯录管理,相当于切换到弹出来的页面 # contacts_management_window.ButtonControl(Name='最大化').Click() if tag: click_tag() # 点击标签 contacts_management_window.PaneControl(Name=tag).Click() time.sleep(0.3) click_tag() # 关闭标签 # 获取滑动模式 scroll = contacts_management_window.ListControl().GetScrollPattern() # assert scroll, "没有可滑动对象" name_list = list() if not scroll: for name_node in contacts_management_window.ListControl().GetChildren(): # 获取当前页面的 列表 -> 子节点 nick_name = name_node.TextControl().Name # 用户名 remark_name = name_node.ButtonControl(foundIndex=2).Name # 用户备注名,索引1会错位,索引2是备注名,索引3是标签名 name_list.append(remark_name if remark_name else nick_name) else: rate: int = int(float(102000 / num)) # 根据输入的num计算滑动的步长 for pct in range(0, 102000, rate): # range不支持float,不导入numpy库,采取迂回这的方式 # 每次滑动一点点,-1代表不用滑动 scroll.SetScrollPercent(horizontalPercent=-1, verticalPercent=pct / 100000) for name_node in contacts_management_window.ListControl().GetChildren(): # 获取当前页面的 列表 -> 子节点 nick_name = name_node.TextControl().Name # 用户名 remark_name = name_node.ButtonControl(foundIndex=2).Name # 用户备注名,索引1会错位,索引2是备注名,索引3是标签名 name_list.append(remark_name if remark_name else nick_name) contacts_management_window.SendKey(auto.SpecialKeyNames['ESC']) # 结束时候关闭 "通讯录管理" 窗口 return list(set(name_list)) # 简单去重,但是存在误判(如果存在同名的好友 def get_group_chat_list(self) -> list: """获取群聊通讯录中的用户名称""" name_list = list() auto.ButtonControl(Name='聊天信息').Click() time.sleep(0.5) chat_members_win = self.wx_window.ListControl(Name='聊天成员') if not chat_members_win.Exists(): return list() self.wx_window.ButtonControl(Name='查看更多').Click() for item in chat_members_win.GetChildren(): name_list.append(item.ButtonControl().Name) return name_list def get_chat_records(self, page: int = 1) -> list: """ 获取聊天列表的聊天记录. Args: page(int): 可选参数,如不指定,只获取1页聊天记录 Returns: list """ chat_records = list() def extract_msg() -> None: all_msgs = self.wx_window.ListControl(Name="消息").GetChildren() for msg_node in all_msgs: msg = msg_node.Name if not msg: continue if msg_node.PaneControl().Name: chat_records.append({'type': 'Time', 'name': 'System', 'msg': msg_node.PaneControl().Name}) continue if msg in ['以下为新消息', '查看更多消息', '该类型文件可能存在安全风险,建议先检查文件安全性后再打开。', '已撤回']: chat_records.append({'type': 'System', 'name': 'System', 'msg': msg}) continue if '撤回了一条消息' in msg or '尝试撤回上一条消息' in msg: chat_records.append( {'type': 'Other', 'name': ''.join(msg.split(' ')[:-1]), 'msg': msg.split(' ')[-1]}) continue if msg in ['发出红包,请在手机上查看', '收到红包,请在手机上查看', '你发送了一次转账收款提醒,请在手机上查看', '你收到了一次转账收款提醒,请在手机上查看']: chat_records.append({'type': 'RedEnvelope', 'name': 'System', 'msg': msg}) continue if '领取了你的红包' in msg: _ = msg.split('领取了你的红包') chat_records.append({'type': 'RedEnvelope', 'name': _[0], 'msg': _[1]}) continue name = msg_node.ButtonControl(foundIndex=1).Name if msg == '[文件]': file_name = msg_node.PaneControl().TextControl(foundIndex=1).Name size = msg_node.PaneControl().TextControl(foundIndex=2).Name chat_records.append( {'type': 'File', 'name': name, 'msg': f'size: {size} --- file_name: {file_name}'}) continue if msg == '微信转账': operation = msg_node.PaneControl().TextControl(foundIndex=2).Name amount = msg_node.PaneControl().TextControl(foundIndex=3).Name chat_records.append( {'type': 'RedEnvelope', 'name': name, 'msg': msg + f' {operation} ' + amount}) continue if '引用' in msg and '的消息' in msg: chat_records.append({'type': 'Cited', 'name': name, 'msg': msg}) continue if msg == '[聊天记录]': if not name: name = msg_node.ButtonControl(foundIndex=2).Name chat_records.append({'type': 'Content', 'name': name, 'msg': msg}) for _ in range(page): self.wx_window.WheelUp(wheelTimes=15) extract_msg() return chat_records def send_msg(self, *names, msgs, file_paths, add_remark_name=False) -> None: """ 发送消息,可同时发送文本和文件(至少选一项 Args: *names (str or Iterable):必选参数,接收消息的好友名称,可以群发,也可以单发 msgs (list): 可选参数,发送的文本消息 file_paths (Iterable):可选参数,发送的文件路径 add_remark_name(bool): 可选参数,是否添加备注名称发送 Returns: None """ assert names, "用户名列表为空" assert any([msgs, file_paths]), "没有发送任何消息" assert not isinstance(msgs, str), "文本必须为可迭代且非字符串类型" assert not isinstance(file_paths, str), "文件路径必须为可迭代且非字符串类型" for name in names: self.__goto_chat_box(name=name) if msgs: if add_remark_name: new_msgs = deepcopy(msgs) new_msgs.insert(0, name) self.__send_text(*new_msgs) else: self.__send_text(*msgs) if file_paths: self.__send_file(*file_paths)

再建一个Python文件为:mytest.py,代码如下:

from wx_file import WxOperation wx = WxOperation() # 发送文本和文件 wx.send_msg('文件传输助手', msgs=["Hello"], file_paths=["F:\Test.txt"]) wx.send_msg('文件传输助手', msgs=["world"], file_paths=["F:\Test.txt"])

但是有时第一次发送不成功,第二次成功。

注意:微信最新版本3.9.5以上代码会发送文件不成功,原因是找不到控件。把电脑版本微信降到上一个版本3.9.2发送成功。

 

仅用于学习交流。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3