python实现微信、QQ聊天自动回复【纯物理】

2023-05-16

一、功能描述

实现微信、QQ等聊天软件的自动回复功能,让你关注的人不用再等候你的回复。通过机器人或者预设消息来自动回答对方的问题。

二、实现方案

0. 方案说明

首先感谢热心网友指出了 itchat 和 wxpy 等插件方案已无法使用的问题,并且看到了基于 hook 的一种方案,不过基于 hook 方案的作者也说明可能有封号风险。

本方案主要构思则是结合各种python库分别实现:界面截图文字识别机器人api调用模拟window键鼠复制文字并发送消息等功能。
从而实现对于打开的指定聊天界面定时识别聊天信息并调用api回复消息的效果。

此外,本方案的图片文字识别功能并没有使用百度AI平台提供的OCR服务,而是使用了免费的本地服务 tesserocr,不需要额外注册,tesserocr 的识别准确率和速度也足够用了,最重要的是免费~

1. 开发环境&工具

conda + python 3.9 + pycharm

2. 必要依赖库安装

2.1 图片操作和文字识别相关库

参考文章:python3.9 安装 tesserocr 过程

  1. tesserocr 文字识别应用安装,下载地址
    本文选用的时目前最新版本的 tesseract-ocr-w64-setup-v5.0.1.20220118,经测试是适配python3.9的。
    安装过程注意:勾选 Additional language data (download) 中的 Chinese-Simplied 中文简体,用于识别中文,其他默认就行
  2. conda install -c simonflueckiger tesserocr pillow
  3. 找到第一步 tesserocr 安装目录下的tessdata 文件夹,全量复制到本地的conda目录下的 /envs/你的python环境对应文件夹 下,如果不知道conda目录在哪里,完成第二步后,运行下面的demo,查看报错中给出的文件路径。
from PIL import Image
import tesserocr

if __name__ == "__main__":
	pic_files = glob.glob('D:\\test.jpg')
	img = Image.open(pic_files[0])
	res = tesserocr.image_to_text(img, lang='chi_sim+eng', psm=6)
	print('识别结果', res)

2.2 剪贴框、键鼠操作库

pip install pyperclip PyUserInput pywin32==225

这里有个坑就是安装了 PyUserInput
虽然
from pymouse import PyMouse
from pykeyboard import PyKeyboard
这两个依赖引入不会报红了,但是编译时会报错“缺失win32api,win32con依赖”,所以需要安装 225 版本的pywin32,这里用最新版本也会报其他错。

三、demo 代码

# !/usr/bin/env python3
# -*- coding: utf-8 -*-
import glob
import re
import os
from os import path
from PIL import ImageGrab, Image
import tesserocr
import time
import json
import requests
import pyperclip
from pymouse import PyMouse
from pykeyboard import PyKeyboard

# 历史消息内存缓存
his_cache = {}
# 截图保存路径
file_path = 'D:\\tmp'
# 监听频率,单位秒
listen_rate = 5
# 是否发送消息标记
send_flag = False
# app类型 WX / QQ
app = 'QQ'

m = PyMouse()
k = PyKeyboard()
# 屏幕分辨率
x_dim, y_dim = m.screen_size()
# 窗口距离屏幕右侧的距离
# offset = 0
offset = 630 if app == 'WX' else 0


def snapshot():
	# 屏幕快照方法
	# (x1, y1), (x2, y2) 用于控制对屏幕聊天截图的范围
	# 最佳范围可以通过单独运行snapshot方法查看截图效果调整
    x1, y1 = int(x_dim * 2 * 3 / 64) + offset, int(y_dim * 2 * 2 / 32)
    x2, y2 = int(x_dim * 2 * 9 / 32) + offset, int(y_dim * 2 * 24 / 32)
    box = (x1, y1, x2, y2)
    pic = ImageGrab.grab(box)
    name = time.strftime("%Y_%m_%d_%H_%M_%S", time.localtime())
    full_path = path.join(file_path, '%s.jpg' % name)
    pic.save(full_path)
    return full_path


def read_img(full_path: str):
	# 聊天记录识别方法
    global his_cache
    message = ''
    robot_key = 'robot_his'
    pic_files = glob.glob(full_path)
    if len(list(pic_files)) > 0:
        file_name = path.basename(pic_files[0])
        img = Image.open(pic_files[0])
        print('\n识别图片:', file_name)
        message = tesserocr.image_to_text(img, lang='chi_sim+eng', psm=6)
        message = str(message)
        # 非法字符过滤,只保留中文文本
        message = re.sub(r'[^\u4E00-\u9FFF]', ' ', message)
        message = re.sub(r'[ ]+', ' ', message)
        message = message.strip()
        print('识别文本:', message)
        arr = message.split(' ')
        if len(arr) > 0:
            message = arr[-1]
        print('最新消息:', message)

	# 及时清理已识别的图片缓存
    if os.path.exists(full_path):
        os.remove(full_path)

    # 历史和当前文本对比
    if len(message) > 0:
        if message.startswith('清空'):
            his_cache = {}
            print('已清空历史消息')
            return ''
        # 读取消息缓存
        msg_his = his_cache.get(robot_key)
        print('历史消息:', msg_his)
        if msg_his:
        	# 当前消息与历史消息对比
            if msg_his == message:
                print('未收到新消息')
                return ''
            # 超长文本情况处理
            i = 0
            while i < len(msg_his):
                msg_s = msg_his[i:]
                if message.startswith(msg_s):
                    msg_arr = message.split(msg_s, 1)
                    if len(msg_arr) > 1:
                        message = msg_arr[1]
                    break
                i += 1
        # 更新消息缓存
        his_cache[robot_key] = message

    return message


def get_dialog(msg: str):
	# 机器人api调用
	answer = 'hello world'
	try:
		# 这里填你自己的机器人接口地址,本文不提供,开源的机器人接口有不少,看个人需求
		url = ''
		sess = requests.get(url)
		answer = sess.text
		# answer = json.loads(answer)
	except Exception as e:
		print(e)
		
	return answer


def mock_msg(msg: str):
	# 模拟键鼠发消息方法
    # 获取机器人回答
    answer = get_dialog(msg)
    print('输入问题:', msg)
    print('返回答案:', answer)
    # 复制文本到剪贴框
    pyperclip.copy(answer)
    pyperclip.paste()
    # 模拟鼠标点击,用于获取聊天软件输入框焦点
    x_pos = int(x_dim * 1/32) + offset
    y_pos = int(y_dim * 28/32)
    # print('x', x_pos, 'y', y_pos)
    m.click(x_pos, y_pos, 1)
    # 模拟键盘点击 ctrl+v,用于将剪贴框文字粘贴到输入框
    k.press_key(k.control_key)
    k.tap_key('v')
    k.release_key(k.control_key)
    # 模拟键盘发送消息
    if app == 'QQ':
        k.press_key(k.control_key)
        k.tap_key(k.enter_key)
        k.release_key(k.control_key)
    elif app == 'WX':
        k.tap_key(k.enter_key)


if __name__ == "__main__":
	# snapshot()
    while True:
        f_path = snapshot()
        f_msg = read_img(f_path)
        if send_flag:
            if len(f_msg) > 0:
                mock_msg(f_msg)
                # 对回复后的聊天界面再次识别,更新界面状态记录
                b_path = snapshot()
                b_msg = read_img(b_path)
                print(b_msg)
        else:
        	# 首次运行不发送消息,只更新消息缓存用于下次对比
            send_flag = True

        time.sleep(listen_rate)

四、操作注意

首先本文demo中设置的分辨率相关参数仅适配作者的电脑,其次如果直接使用demo中的参数,建议将聊天软件界面放到屏幕左半边,并将上下长度拉满!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python实现微信、QQ聊天自动回复【纯物理】 的相关文章

  • 模拟退火解决TSP问题

    模拟退火解决TSP问题 模拟退火 https mp weixin qq com s src 61 11 amp timestamp 61 1633564978 amp ver 61 3359 amp signature 61 oeLMbNZ
  • Neo4j 下载安装

    Neo4j 下载安装 Windows Neo4j community 新旧版本下载 旧版本在官网上已经找不到了 xff0c 新旧版本的区别在于登录是否需要密码 Windows Neo4j community 2 0 1及2 1 0 不需要密
  • 【libuv】1.44 windows构建

    uv a 作为一个独立的工程构建的 c 工程里c符号找不到 链接不过 Build started span class token punctuation span span class token operator span class
  • SEU健康申报+离校请假

    SEU健康申报 43 离校请假 Github源码 通过对源码的学习修改 xff0c 本程序稍作调整 xff0c 将健康申报 销假和请假模块分开 xff0c 目前可用 配置 chromedriver下载方法 xff0c 将下载的chromed
  • ValueError: Please provide model inputs as a list or tuple of 2 or 3 elements: (input, target)

    ValueError Please provide model inputs as a list or tuple of 2 or 3 elements input target 报错信息 Traceback span class toke
  • tensorflow checkout 的作用

    tensorflow checkout 的作用 参考链接如下 xff1a Tensorflow保存恢复模型及微调 网络模型的保存和读取 tensorflow训练保存的模型 模型文件夹中的文件主要为以下三类 xff1a checkpoint
  • afl-fuzz多线程

    afl fuzz多线程 afl fuzz多线程 https blog csdn net lesliegail1 article details 70209351 首先 xff0c 我们阅读这篇博客对afl fuzz单机多线程进行了解 我们了
  • 将同一文件夹下的大量文件根据设定分至多组

    将同一文件夹下的大量文件根据设定分至多组 需求分析 在recon文件夹下存在大量文件 xff0c 观察文件名 xff0c 我们设计将文件按照recon 后的第一个数字进行分组 xff0c 那么最终产生的文件夹应为0 1 11 编写程序 基于
  • CCF 202206-4 光线追踪 python

    CCF 202206 4 光线追踪 python CCF官网题目 此题因为运行超时得到了30分 xff0c 仅为没思路的同学提供一些想法 xff0c 如果有改进建议欢迎评论 xff01 题目分析 首先将反射镜转换为单独的反射点 xff0c
  • AutoEncoder及Variational AutoEncoder模型

    AutoEncoder及Variational AutoEncoder模型 一 AutoEncoder概述 作为一种无监督或者自监督算法 xff0c 自编码器本质上是一种数据压缩算法 从现有情况来看 xff0c 无监督学习很有可能是一把决定
  • CCF-CSP【202303-3 LDAP】C++

    CCF CSP 202303 3 LDAP C 43 43 CCF真题网址 第一次提交结果超时 只有20分 题目思路 我的思路较为简单 xff0c 即对于每个匹配表达式 xff0c 遍历N个用户 xff0c 验证是否匹配 对于每个表达式有两
  • 2的幂次方

    2的幂次方 判断一个数是否为2的幂次方 我们可以参考如下链接 xff1a 判断一个数是否为2的N次方 借鉴文中的分析 xff0c 我认为 xff1a 其实一个数n xff0c 如果是2的幂次方数 xff0c 则n的二进制原码中一定只有一个1
  • 爬虫1000+个C程序

    爬虫1000 43 个C程序 问题场景 由于实验需要 xff0c 我需要1000 43 个elf文件 xff0c 可是网络可获取的elf文件较少 xff0c c程序较多 xff0c 所以首先下载c程序 xff0c 之后gcc编译链接生成el
  • 【libuv】定时器:uv_timer_start 的timeout和repeat 参数

    花了好几个小时验证 uv timer start 发现怎么都是错误的 现象是 repeat 作为了timeout的效果 而且repeat 代表是毫秒级别的 按照原有设计 timeout是微秒 repeat的参数并不是timeout参数 而且
  • 解决IDEA Maven依赖下载总是失败的几种方法

    为啥我的IDEA Maven依赖下载总是失败 xff1f xff1f 我们本地使用 IDEA 运行 maven 项目的时候 xff0c 有时候运气不好 xff0c 就会遇到某些 maven 依赖无法正常找到 导入 这就会导致 IDEA 构建
  • 几种常见排序算法的实现及运行时间对比

    冒泡排序 function popSort arr if arr length lt 2 return arr let n 61 arr length while n gt 1 let exchanged 61 false for let
  • FtpClient切换、创建目录不成功的问题(makeDirectory、changeWorkingDirectory)

    FtpClient切换 创建目录不成功的问题 xff08 makeDirectory changeWorkingDirectory xff09 做功能时切换目录老是不成功且无法创建文件夹 xff0c 翻阅一些博客后发现Ftp创建目录只能逐级
  • RNA-seq数据上游分析流程(从原始数据开始)

    数据分析的基本思路 xff08 1 xff09 从ncbi的geo或者其它数据库中查找自己感兴趣的RNASeq数据 xff0c 至少要求给出如下信息 xff1a xff08 2 xff09 对芯片数据进行质量控制评价及处理 xff08 如果
  • R语言2——数据类型和基本运算

    R语言2 数据类型和基本运算 目录 R语言2 数据类型和基本运算 1 R的数据类型 1 R的数据类型 xff08 1 xff09 Logical xff08 逻辑型 xff09 xff1a 只有两个值TRUE FALSE xff08 2 x
  • 红芯对chromium,瞩目对zoom。扒扒瞩目客户端。

    0x00 前提 一直以来 xff0c 人们普遍怀疑瞩目等 国产 云会议系统在界面 xff0c 功能上有剽窃国外的Zoom us的嫌疑 xff0c 但无证据 本文从瞩目的Ubuntu客户端入手 xff0c 详细证明了瞩目的Zoom血统 0x0

随机推荐