吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2936|回复: 24
收起左侧

[Python 转载] python模拟键鼠,发送微信消息,支持命令行调用,可作为模块使用

[复制链接]
wkdxz 发表于 2022-8-12 16:13
本帖最后由 wkdxz 于 2022-8-13 10:05 编辑

一直以来都是使用AHK来操作微信发消息的,最近看到@yuupuu帖子,看到python控制微信也比较稳定,而且写代码更简单,于是也参照原贴写了一个。
因为是在Excel里面使用代码,所以就做了参数调用,可以使用命令行运行
为避免以后重复书写,就做成了一个简陋的模块,可以直接import调用
命令行不方便传入多行文字,于是增加了直接发送剪贴板的功能。
因为是使用剪贴板来复制粘贴输入文字和文件,所以增加了还原剪贴板数据的功能。


2022-08-13更新:不再强制修改微信窗口大小和位置,使用相对坐标点击。

发送微信消息.zip (3.49 KB, 下载次数: 34)

代码功能是东拼西凑的,不够精简和完善,喜欢的朋友可以拿去用。
这里的0.25是鼠标点击的延迟 0.25秒,如果电脑反应慢,可以增加这个数值。
[Python] 纯文本查看 复制代码
def click(self, x, y, timeout=0.25): 



除了主代码,另外两个是示例文件,喜欢的朋友可以下载来用。
Snipaste_2022-08-12_16-03-53.jpg



主代码:wx_sender.py
[Python] 纯文本查看 复制代码
from pyperclip import copy, paste
from time import sleep
import ctypes
import pyautogui
import sys
import win32clipboard
import win32con
import win32gui


class DROPFILES(ctypes.Structure):
    _fields_ = [
        ("pFiles", ctypes.c_uint),
        ("x", ctypes.c_long),
        ("y", ctypes.c_long),
        ("fNC", ctypes.c_int),
        ("fWide", ctypes.c_bool),
    ]


def restore_clipboard(func):  #自动还原剪贴板
    def wrapper(*args, **kwargs):
        clip_bak = paste()  # 备份
        result = func(*args, **kwargs)
        copy(clip_bak)  #还原
        return result

    return wrapper


class WxMsg:
    def __handle(self):
        return win32gui.FindWindow('WeChatMainWndForPC', '微信')

    def __pos_and_size(self):
        win_x, win_y, win_right_down_x, win_right_down_y = win32gui.GetWindowRect(
            self.__handle())
        win_width = win_right_down_x - win_x
        win_height = win_right_down_y - win_y
        return win_x, win_y, win_width, win_height

    #复制文件到剪贴板 代码来源:https://www.cnblogs.com/love-DanDan/p/15900159.html
    def __copy_file(self, files):
        pDropFiles = DROPFILES()
        pDropFiles.pFiles = ctypes.sizeof(DROPFILES)
        pDropFiles.fWide = True
        mdata = bytes(pDropFiles)
        files = ("\0".join(files)).replace("/", "\\")
        data = files.encode("U16")[2:] + b"\0\0"
        win32clipboard.OpenClipboard()
        try:
            win32clipboard.EmptyClipboard()
            win32clipboard.SetClipboardData(win32clipboard.CF_HDROP,
                                            mdata + data)
        finally:
            win32clipboard.CloseClipboard()

    #打开窗口  代码来源: 【yuupuu】 [url]https://www.52pojie.cn/thread-1673429-1-1.html[/url]
    def __activate_wx_window(self):
        if handle := self.__handle():
            win_x, win_y, win_width, win_height = self.__pos_and_size()
            win32gui.ShowWindow(handle, win32con.SW_SHOWMINIMIZED)
            win32gui.ShowWindow(handle, win32con.SW_SHOWNORMAL)
            win32gui.ShowWindow(handle, win32con.SW_SHOW)
            win32gui.SetWindowPos(handle, win32con.HWND_TOP, win_x, win_y,
                                  win_width, win_height,
                                  win32con.SWP_SHOWWINDOW)
            win32gui.SetForegroundWindow(handle)
        else:
            print('微信未登录')
            exit()

    #复制文字,并粘贴
    @restore_clipboard
    def __wx_input(self, txt):
        copy(txt)
        pyautogui.hotkey('ctrl', 'v')

    #延时点击坐标
    #默认使用相对坐标点击 (实际点击位置:窗口坐标+相对坐标)
    def __click(self, x, y, timeout=0.25, relative=True):  #默认使用相对坐标点击
        sleep(timeout)
        win_x, win_y = self.__pos_and_size()[:2]
        if relative:
            pyautogui.click(win_x + x, win_y + y)  #使用相对坐标点击
        else:
            pyautogui.click(x, y)

        #把消息发送出去
    def __send_msg_out(self):
        sleep(0.4)
        pyautogui.hotkey('alt', 's')

    #搜索联系人
    def search(self, wxid):
        self.__activate_wx_window()
        self.__click(21, 145)  # 通讯录
        self.__click(143, 39)  # 搜索框
        self.__wx_input(wxid)  # 搜索微信id
        self.__click(155, 120, 0.6)  # 点第一个搜索结果 要多停留一会儿

        #点输入框,从微信窗口右下角:x-50,y-63,使用绝对坐标点击
        win_right_down_x, win_right_down_y = win32gui.GetWindowRect(
            self.__handle())[-2:]  #微信窗口右下角的坐标
        self.__click(win_right_down_x - 50, win_right_down_y - 63, 0.2, False)

    #发送文字消息
    @restore_clipboard
    def send_txt(self, txt, send_out=True):
        copy(txt)  # 粘贴文本内容
        pyautogui.hotkey('ctrl', 'v')  # 粘贴复制的内容
        if send_out:
            self.__send_msg_out()

    #发送文件,传入参数为文件路径
    @restore_clipboard
    def send_file(self, file_list, send_out=True):
        if isinstance(file_list, str):
            file_list = [file_list]
        self.__copy_file(file_list)
        pyautogui.hotkey('ctrl', 'v')  # 粘贴复制的内容
        if send_out:
            self.__send_msg_out()

    #直接发送剪贴板内容
    def send_clipboard(self, send_out=True):
        if paste():
            pyautogui.hotkey('ctrl', 'v')  # 粘贴复制的内容
            if send_out:
                self.__send_msg_out()
        else:
            print('剪贴板为空')
            exit()


if __name__ == '__main__':
    arg_count = len(sys.argv)  #传入的参数个数

    if arg_count not in {1, 2, 3, 4}:
        print('参数个数不是2或3,看看是不是传入了含空格的文件路径')
    else:
        wx = WxMsg()  #实例化对象

        # 3个参数发文件
        if arg_count == 4:  # 传入3个参数(微信id,消息内容,文件路径)
            _, wxid, msg_content, msg_type = sys.argv
            if msg_type.lower() == 'f':
                wx.search(wxid)  #搜索微信号
                wx.send_file(msg_content)  # 发送1个文件
            else:
                print(f'第3参数【{msg_type}】错误,必须是“f”\n可以检查下是不是传入了含空格的文件路径')

        # 2个参数发文字
        elif len(sys.argv) == 3:  # 传入2个参数(微信id,文字消息内容)
            _, wxid, msg_content = sys.argv
            wx.search(wxid)  #搜索微信号
            wx.send_txt(msg_content)

        # 1个参数发剪贴板内容
        elif len(sys.argv) == 2:  # 传入1个参数(微信id)
            _, wxid = sys.argv
            wx.search(wxid)  #搜索微信号
            wx.send_clipboard()

        ################################ 不传入参数,直接在python里运行,可以发送多行文本或者多个文件
        elif arg_count == 1:
            wxid = '小号'  #要发送的微信号
            wx.search(wxid)  #搜索微信号

            # 发送1条消息
            wx.send_txt('测试1条消息')

            # # 发送1个文件
            # wx.send_file(r'C:\Windows\write.exe')

            # # 发送多个文件,传入[文件路径列表]
            # sleep(1)
            # wx.send_file([r'C:\Windows\write.exe', r'C:\Windows\hh.exe'])

            # # 发送多条文字消息
            # sleep(1)
            # for i in range(5):
            #     wx.send_txt(f'发送第{i+1}条文字消息')
            #     sleep(1)

            # #粘贴消息,不发送出去
            # wx.send_txt('此消息不会发送出去,因为添加了第二参数 False', False)


使用Python可以轻松调用
[Python] 纯文本查看 复制代码
from wx_sender import WxMsg
from time import sleep

wx = WxMsg()  #实例化对象

wxid = '小号'  #要发送的微信号
wx.search(wxid)  #搜索微信号

# 发送剪贴板内容
wx.send_clipboard()

# 发送1条消息
wx.send_txt('测试单条消息')

# 发送1个文件
wx.send_file(r'C:\Windows\write.exe')

# 发送多个文件,传入[文件路径列表]
sleep(1)
wx.send_file([r'C:\Windows\write.exe', r'C:\Windows\hh.exe'])

# 发送多条文字消息
sleep(1)
for i in range(5):
    wx.send_txt(f'发送第{i+1}条文字消息')
    sleep(1)

#粘贴消息,不发送出去
wx.send_txt('此消息不会发送出去,因为添加了第二参数 False', False)



使用命令行调用
[Asm] 纯文本查看 复制代码
@echo off & pushd %~dp0

set wxid=小号

::发送文字消息
.\wx_sender.py %wxid% 测试消息


echo 按任意键测试发送文件&pause>nul

::发送文件,在后面加上参数f
.\wx_sender.py %wxid% "C:\Windows\write.exe" f


echo 按任意键测试发送剪贴板&pause>nul

::发送剪贴板内容
.\wx_sender.py %wxid%

免费评分

参与人数 6吾爱币 +11 热心值 +6 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zyhxhw + 1 + 1 热心回复!
Fireworks0435 + 1 我很赞同!
放羊的狼 + 1 + 1 我很赞同!
wanfon + 1 + 1 热心回复!
zhangchang123 + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| wkdxz 发表于 2022-8-12 17:22
本帖最后由 wkdxz 于 2022-8-12 17:35 编辑
放羊的狼 发表于 2022-8-12 17:01
看楼主说的是在Excel中使用,那...sendkeys不一样能搞定吗,前阵子写过一个目前一直在用,貌似比较稳定,文 ...

正好VBA,python和AHK 我都在用。
vba别的不说,就延时一点就很卡,操作过程一直转圈,容易崩溃,可能是我技术不行或者WPS软件的问题。
AHK可以使用相对坐标点击,不用把微信窗口固定大小,放到左上角,但代码太不严谨,可参照的示例也没有python丰富。
python虽然要把微信窗口固定大小,放到左上角,但代码写起来很灵活,也有大堆的库可以调用。

后两者都可以使用cmd调用。所以,使用AHK或python书写,我还可以使用AHK快捷键来搜索联系人和发送微信消息。
A小虎 发表于 2022-8-12 16:23
miaogong 发表于 2022-8-12 16:38
cdsgg 发表于 2022-8-12 16:41
这种坐标的 如果不是绝对坐标的 估计到时候可能会出错 玩wx这种东西还是得靠hook
JiaoDaoNiu 发表于 2022-8-12 16:45
这个有啥好的应用场景吗
aa702429162 发表于 2022-8-12 16:54
JiaoDaoNiu 发表于 2022-8-12 16:45
这个有啥好的应用场景吗

微信啊,已经没有api了,用这个模拟发消息很不错
放羊的狼 发表于 2022-8-12 17:01
看楼主说的是在Excel中使用,那...sendkeys不一样能搞定吗,前阵子写过一个目前一直在用,貌似比较稳定,文本、@成员、文件都可以通过剪贴板处理。前几天测试过ahk并不稳定(可能是我比较菜,毕竟只了解了两三天),python不了解,但看你代码也是模拟按键,貌似绕路绕得有点远。
edmin 发表于 2022-8-12 18:47
怎么运行呀
-白衬衫- 发表于 2022-8-12 19:28
这个要一直在前台运行吧?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-20 02:15

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表