文章目录
前言
在这个数字化时代,微信已经成为我们日常生活中不可或缺的一部分,它不仅仅是一个即时通讯工具,更是一个强大的营销平台。然而,随着用户基数的不断增长,如何高效地管理和利用微信进行营销推广,成为了众多企业和个人所面临的一大挑战。
在这篇文章中,博主将带你一起探索如何从零开始,使用Python的Flask框架和UIAutomation技术,构建一个RPA微信自动群发工具。这不仅是一个技术实践的过程,更是一次深入理解自动化和Web开发的机会。
提示:以下是本篇文章正文内容,下面案例可供参考
一、环境搭建
系统要求
- 操作系统:本教程将仅适用于Windows系统。
- Python:推荐使用Python 3.6及以上版本。Python是一种广泛使用的高级编程语言,非常适合快速开发。
flask安装
Flask是一个轻量级的Web应用框架,我们将使用它来构建后端服务。
- 打开命令行。
- 输入以下命令来安装Flask:
pip install flask
uiautomation安装
UIAutomation是一个用于自动化用户界面操作的库,我们将用它来模拟微信操作。
- 打开命令行。
- 输入以下命令来安装uiautomation:
pip install uiautomation
二、群发功能的实现
要导入的包
import os
import time
import subprocess
import uiautomation as auto
from typing import Iterable
1.构建WxOperation类
class WxOperation:
"""微信群发消息的类。"""
def __init__(self):
auto.SendKeys(text='{Alt}{Ctrl}w') # 快捷键唤醒微信
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='搜索')
2.搜寻被发送人
代码如下(示例):
def __goto_chat_box(self, name: str) -> None:
"""跳转到指定 name好友的聊天窗口"""
assert name, "无法跳转到名字为空的聊天窗口"
self.wx_window.SendKeys(text='{Ctrl}f', waitTime=0.1)
self.wx_window.SendKeys(text='{Ctrl}a', waitTime=2)
self.wx_window.SendKey(key=auto.SpecialKeyNames['DELETE'])
self.search_edit.SendKeys(text=name, waitTime=2)
self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=2)
注意:waitTime时间不可过短 原因:1. 避免被微信屏蔽 2. 给搜索一定的时间
3. 发送文本
def __send_text(self, *msgs) -> None:
"""发送文本"""
for msg in msgs:
assert msg, "发送的文本内容为空"
self.__edit_message(msg)
self.wx_window.SendKeys('{Enter}', waitTime=0)
#为了解决微信发送文本不能换行的问题
def __edit_message(self,msg):
temp = ""
for char in msg:
if char == '*':
self.wx_window.SendKeys(temp, waitTime=1)
self.wx_window.SendKeys('{Shift}{Enter}', waitTime=0)
self.wx_window.SendKeys('{Shift}{Enter}', waitTime=0)
temp = ""
else:
temp += char
if temp:
self.wx_window.SendKeys(temp, waitTime=1)
4.发送文件
def __send_file(self, *file_paths) -> 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']
subprocess.Popen(args=args)
time.sleep(0.5)
self.wx_window.SendKeys('{Ctrl}v', waitTime=0.2)
self.wx_window.SendKeys('{Enter}', waitTime=0)
5.接收消息
def send_msg(self, *names: str or Iterable, msgs: Iterable = None, file_paths: Iterable = None) -> 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:
self.__send_text(*msgs)
if file_paths:
self.__send_file(*file_paths)
三、构建后端服务
要导入的包
from flask import Flask, render_template, request, redirect, url_for
import os
import time
import subprocess
import pythoncom
import uiautomation as auto
from typing import Iterable
import pandas as pd
文件框架
- templats
- index.html - app.py
1. index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微信群发消息</title>
<style>
textarea{
width: 100%;
height:150px;
padding: 10px;
box-sizing: border-box;
}
</style>
</head>
<body>
<h1>微信群发消息</h1>
<form method="POST" enctype="multipart/form-data">
<label for="excel_file">上传包含群名称的Excel文件:</label>
<input type="file" id="excel_file" name="excel_file" accept=".xlsx"required><br><br>
<label for="msgs">消息 (以英文逗号分隔,换行用‘*’):</label>
<!-- <input type="text" id="msgs" name="msgs"><br><br> -->
<textarea id ="msgs" name = "msgs"></textarea><br><br>
<label for="files">选择文件:</label>
<input type="file" id="files" name="files" multiple><br><br>
<input type="submit" value="发送">
</form>
</body>
</html>
2. app.py
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
excel_file = request.files['excel_file']
excel_path = os.path.join('uploads',excel_file.filename)
excel_file.save(excel_path)
df = pd.read_excel(excel_path)
names = df['Name'].dropna().tolist()
# names = request.form.get('names').split(',')
msgs = request.form.get('msgs').split(',')
file_paths = request.files.getlist('files')
file_paths_list = []
for file in file_paths:
if file.filename:
file.save(os.path.join('uploads', file.filename))
file_paths_list.append(os.path.join('uploads', file.filename))
wx = WxOperation()
wx.send_msg(
*names,
msgs=msgs if msgs != [''] else None,
file_paths=file_paths_list if file_paths_list else None
)
return redirect(url_for('index'))
return render_template('index.html')
if __name__ == '__main__':
if not os.path.exists('uploads'):
os.makedirs('uploads')
app.run(debug=True)
注意:不要忘记引入WxOperation类
四、成果展示
该网页允许发送多条消息或者不发,发送多份文件或者不发。
注意发送多份文件时要一次性选中
总结
在这篇文章中,我们探索了如何利用Flask和UIAutomation技术构建一个微信自动群发工具。我们从项目的目标和预期成果开始,逐步深入到技术细节,最终提供了一个全面的解决方案。