初学Python第三天写的一个PC版模拟微信自动给好友发送消息

本程序能做什么:

在PC版的微信界面,模拟鼠标键盘动作,随机对好友列表里的某些好友发送文本消息和图片

(因为本人以前没有WINDOW UI的编程经验,所以这几天对WIN32UI接口基本是边学边搜边用,导致程序里面导入的UI包资源有功能上的冗余,比如WIN32API和pyautogui代码都有混合重叠,目的只是实现自己需要的功能,也就不要太计较了)

# 第一步需要手动登录PC版微信

# 因为显示器分辨率的不同,程序文件的各个常量需要手工设置一下,否则鼠标可能无法准确点击微信功能界面

# 开始运行本Python程序,会自动把微信最大化并最靠前,然后依次对好友列表内的好友发送预置的文本信息和图片

#在INI文件里可以设置需要发送的好友列表的页数,需要发送的文本信息,以及图片所在文件夹的路径(图片文件夹下面的所有图片随机发送)

INI文件内容:

[DataLoading]
friendListPages = 1
imageDir = 
sendMsg = 您好,请关注一下!
import win32gui, win32api, win32con
import win32clipboard as clipboard
import pyperclip
import pyautogui
import time
import random
import configparser
from PIL import Image
from io import BytesIO
import os

# 要定位的窗口信息常量
WINDOW_NAME = '微信'
WINDOW_CLASS = 'WeChatMainWndForPC'

# 联系人按钮入口鼠标位置
FRIENDS_IN_XPOS = 30
FREENDS_IN_YPOS = 140

# 联系人详细列表鼠标X坐标位置
PEOPLE_XPOS = 200

# 好友详细列表居中X坐标位置
PEOPLE_LIST_MID_XPOS = 180
# 联系人详细列表鼠标Y坐标起始位置
PEOPLE_LIST_START_YPOS = 70
# 每个联系人列表的高度
PEOPLE_ONE_HEIGHT = 60

# 微信在屏幕中最低位置标记
SCREEN_LOWEST_POS = 730
# 右键向上弹出菜单的最低屏幕位置
RMENU_UPDOWN_POS= 653

# 点击好友详细列表右侧滚动条向下的位置
FRIENDS_LIST_SCROLL_XPOS = 308
FRIENDS_LIST_SCROLL_YPOS = SCREEN_LOWEST_POS - 2

# 点击当前的位置
current_friend_y_pos = 0

# 好友列表页面计数
FRIEND_LIST_MAXPAGES = 70
friend_list_pageCount = 1

# 发送好友消息计数
friend_sendMsgCount = 0

# 图片目录
IMAGE_DIR = 'D:\\PythonProjects\\Hello\\GoodsPics\\'
# 自定图片目录下的所有图片的名称列表
ALL_IMAGES_LIST = []
# 发送给好友的文本信息
SEND_MSG = ''
# 每次发送给好友的图片数量
SEND_IMAGE_TIMES = 1
# 发送文本消息的分隔符
MSG_SPLIT_FLAG = '%%'
send_msg_list = []


def _ini():
    global FRIEND_LIST_MAXPAGES
    global IMAGE_DIR
    global ALL_IMAGES_LIST
    global SEND_MSG
    global SEND_IMAGE_TIMES
    global MSG_SPLIT_FLAG
    global send_msg_list

    # 从配置文件里读取初始值
    configure = configparser.ConfigParser()
    configure.read('configure.ini')
    section = configure['DataLoading']
    if int(section['friendListPages']) > 0:FRIEND_LIST_MAXPAGES = int(section['friendListPages'])
    if len(section['imageDir']) > 0:IMAGE_DIR = section['imageDir']
    if len(section['sendMsg']) > 0:SEND_MSG = section['sendMsg']
    if int(section['sendImageTimes']) > 0:SEND_IMAGE_TIMES = int(section['sendImageTimes'])
    if len(section['msgSplitFlag']) > 0:MSG_SPLIT_FLAG = section['msgSplitFlag']

    # 将要发送的文本消息列表,随机挑选消息
    send_msg_list = SEND_MSG.split(MSG_SPLIT_FLAG)

    ALL_IMAGES_LIST = _getAllImagesPathList()


# 

def getLocalImageData(path):
    img = Image.open(path)
    output = BytesIO()  # BytesIO实现了在内存中读写bytes
    # output = StringIO()  # StringsIO实现了在内存中读写bytes
    img.convert("RGB").save(output, "BMP") #以RGB模式保存图像
    data = output.getvalue()[14:]
    output.close()
    img.close()
    return data

# 把图片数据内容塞入剪贴板
def setImageDataToClipboard(data):
    clipboard.OpenClipboard()
    clipboard.EmptyClipboard()
    clipboard.SetClipboardData(win32con.CF_DIB, data)
    clipboard.CloseClipboard()


# 清空剪贴板
def clearClipboard():
    clipboard.OpenClipboard()
    clipboard.EmptyClipboard()
    clipboard.CloseClipboard()


# 按照提供的图片路径装载图片到剪切板
def loadImageToclipboard(path):
    setImageDataToClipboard(getLocalImageData(path))


# 复制文字到剪贴板
def _loadTextToClipboard():
    pyperclip.copy(send_msg_list[random.randint(0, len(send_msg_list) - 1)])


# 得到指定图片目录下面的所有图片列表
def _getAllImagesPathList():
    return os.listdir(IMAGE_DIR)

def _loadSendMsg():
    # 首先清空剪贴板
    clearClipboard()

    # 装载将要发送的文本信息到剪贴板
    _loadTextToClipboard()
    _clipboardSendMsg()

    for i in range(1, SEND_IMAGE_TIMES + 1):
        # 随机装载图片到剪贴板
        loadImageToclipboard(IMAGE_DIR + 
                                ALL_IMAGES_LIST[random.randint(0, len(ALL_IMAGES_LIST) - 1)])
        _clipboardSendMsg()

        _sleepLongTime()

        i += 1


# 把粘贴板里的内容,粘帖到微信里,然后发送出去
def _clipboardSendMsg():
    # win32api.keybd_event(17, 0, 0, 0)                           # ctrl的键位码是17  
    # win32api.keybd_event(86, 0, 0, 0)                           # v的键位码是86  
    # win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0)    # 释放按键  
    # win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)

    # 粘帖到微信
    pyautogui.hotkey('ctrl', 'v')

    _sleepLongTime()

# 发送消息动作
def _sendMsgAction():
    
    win32api.keybd_event(13, 0, 0, 0)                           # Enter的键位码是13  
    win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)

    _sleepLongTime()


# 为了给界面切换足够的时间,需要适当的间隔时间
def _sleepShortTime():
    time.sleep(0.5)
def _sleepLongTime():
    time.sleep(1)


# 找到窗口,让窗口位置靠最前,并最大化
def _controlWindow():
    # 获取窗口句柄
    hw = win32gui.FindWindow(None, WINDOW_NAME)
    hw = win32gui.FindWindow(WINDOW_CLASS, None)

    if hw <= 0:return -1

    # 让窗口在最前面
    win32gui.SetForegroundWindow(hw)
    # 让窗口最大化
    win32gui.ShowWindow(hw, win32con.SW_MAXIMIZE)

    return 1


# 点击联系人按钮
def _clickFriendsList():
    # 将鼠标移动到坐标处
    pyautogui.moveTo(FRIENDS_IN_XPOS, FREENDS_IN_YPOS, duration = 0)

    # 左点击,准备进入联系人列表界面
    pyautogui.click()

    _sleepLongTime()


# 在好友列表滚动鼠标,换下一批好友
def _scrollNextFriendList():
    # 将鼠标移动到坐标处
    pyautogui.moveTo(PEOPLE_LIST_MID_XPOS, PEOPLE_LIST_START_YPOS, duration = 0)
    # 鼠标滚轮滚动好友列表
    pyautogui.scroll(-2200)

    _sleepLongTime()

    return 1


# 右键点击联系人,然后发送粘贴板里的消息
def _rbClickSendMessage(xPos, yPos):
    global friend_sendMsgCount


    # 将鼠标移动到坐标处
    pyautogui.moveTo(xPos, yPos, duration = 0)

    _sleepShortTime()

    # 右键点击出弹出菜单,点击发消息选项
    pyautogui.rightClick()

    _sleepShortTime()

    if yPos <= RMENU_UPDOWN_POS:
        pyautogui.moveTo(xPos + 15, yPos + 15, duration = 0)

        _sleepShortTime()

        # 左键点击菜单,准备进入联系人列表界面
        pyautogui.click()
    else:
        pyautogui.moveTo(xPos + 15,  yPos - 100, duration = 0)

        _sleepShortTime()

        # 左键点击菜单,准备进入联系人列表界面
        pyautogui.click()
    

    _sleepShortTime()

    # 装载要发送的消息到剪切板,然后复制到微信里
    _loadSendMsg()

    friend_sendMsgCount += 1

    # 发送消息出去
    _sendMsgAction()


def _random_friend_yPos():
    return random.randint(1, 
                    int((SCREEN_LOWEST_POS - PEOPLE_LIST_START_YPOS) / PEOPLE_ONE_HEIGHT)) * PEOPLE_ONE_HEIGHT


# 判断是不是好友列表是不是最后一页,为程序结束最准备
def _isLastPage():
    return False

if __name__ =='__main__':
    # 首先找到窗口
    if _controlWindow() == -1:exit()

    _sleepLongTime()

    # 初始化
    _ini()

    while 1:
        # 点击联系人按钮,准备进入联系人列表
        _clickFriendsList()

        # 判断当前点击位置如果不在有效范围内,设置初始值。
        if current_friend_y_pos == 0:
            current_friend_y_pos = PEOPLE_LIST_START_YPOS - PEOPLE_ONE_HEIGHT

        current_friend_y_pos += _random_friend_yPos()

        if current_friend_y_pos > SCREEN_LOWEST_POS:
            current_friend_y_pos = 0

            # 在好友列表滚动鼠标,换下一批好友
            _scrollNextFriendList()

            print('已完成' + str(friend_list_pageCount) + '页')

            # 如果是最后一页,结束程序
            if _isLastPage():exit()

            friend_list_pageCount += 1

            if friend_list_pageCount > FRIEND_LIST_MAXPAGES:
                print('共发送给' + str(friend_sendMsgCount) + '个好友')
                print('执行完毕!')
                exit()

            continue
        
        # 右键点击好友,然后发送粘贴板里的消息
        _rbClickSendMessage(PEOPLE_XPOS, current_friend_y_pos)

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值