python 基于OCR视觉识别 + deepseek 实现的微信AI机器人
在我上一篇文章里,我曾简要介绍并实现了一个基于 Python 与 DeepSeek 的微信 AI 机器人工具。这个工具曾稳定运行了一段时间,然而好景不长,随着微信强制进行版本更新,它最终还是“折戟沉沙”了。究其原因,大概是微信高版本对 UI 树进行了隐藏处理,致使之前设计的逻辑思路全盘崩溃。市面上不少同类脚本工具也受到了波及。尽管有技术大佬想出了各种应对方案,但在我看来,若继续沿着这条路走下去,被
python 基于OCR视觉识别 + deepseek 实现的微信AI机器人
前言
在我上一篇文章里,我曾简要介绍并实现了一个基于 Python 与 DeepSeek 的微信 AI 机器人工具。这个工具曾稳定运行了一段时间,然而好景不长,随着微信强制进行版本更新,它最终还是“折戟沉沙”了。究其原因,大概是微信高版本对 UI 树进行了隐藏处理,致使之前设计的逻辑思路全盘崩溃。市面上不少同类脚本工具也受到了波及。尽管有技术大佬想出了各种应对方案,但在我看来,若继续沿着这条路走下去,被动地跟随微信的更新节奏进行维护,无疑是一件极为麻烦且耗费精力的事情。于是,我开始积极探寻新的实现方法。
在与朋友的一次闲聊中,他提到了 OCR 技术,这犹如一盏明灯,为我指明了新的方向。我当机立断,果断舍弃了之前的代码,新建了项目文件夹,准备大干一场。
下面我来阐述一下我的整体思路:首先,打开微信并将其窗口最大化;接着,对当前界面进行截图,以此作为初始模板;然后,运用 OCR 技术定位搜索框,并模拟键鼠操作,在搜索框中输入指定内容进行聊天搜索;之后,单独截取该聊天区域的图片,避免其他文本对数据造成干扰;再通过 OCR 技术识别聊天区域内的文字内容及其位置信息;随后,编写相应的算法逻辑,依据文字位置对其进行分类处理;最后,将处理好的结果提供给 DeepSeek,让它给出精准的回答,并模拟键鼠操作将其发送出去,过程全部自动。
相同思路的代码,可以只做细微便应用于QQ、钉钉等相似的聊天软件上。
光学字符识别(OCR)是指通过电子设备检测纸质文档中的字符,利用图像处理与模式识别技术将文字转换为可编辑文本的计算机视觉技术。其流程包含图像预处理、文本检测、字符识别等核心模块,其中提升识别正确率的ICR(智能字符识别)是其重要课题。2020年9月,国内首份智能文字识别能力测评与应用白皮书正式发布。
测试效果图


这里开头有点中二,是因为我很久之前用这个账号测试二次元人物博士尊人设的AI导致的,目前设置的人设会自动根据你之前的聊天来改变,目的是让对方尽量感觉不到你是个AI,而是你本人在跟对方聊天。
另外我还新增了一个贴吧暴躁老哥的人设,攻击力这块,我只能说无敌了,99%过不了审,就不在这里发了,大家可以获取项目后自行体验。
技术栈
- python 3.12
- OCR:网易有道智云API
- AI:deepseek API
目录结构

AI文件:deepseek API接口对接,AI相关函数定义,AI参数、提示词等相关设置
OCR文件:使用了官方提供的demo,只进行了细微的改动
image文件:用于提供给OCR进行分析定位等功能
main:主要执行文件,运行该文件可执行此脚本
源代码
代码文件较多,这只提供主函数代码作为参考,完整项目可访问我的GitHub仓库免费获取。
import json
import cv2
import pyautogui
import pyperclip
import pygetwindow
import os
import time
import AI.AI
from PIL import ImageGrab
from typing import List, Dict, Any, Tuple
from Ocr.Ocr import createRequest
# 查找图片在模板中的位置,返回中心点坐标
def find_img(target_path, source_path):
target = cv2.imread(target_path)
template = cv2.imread(source_path)
result = cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
return max_loc[0] + target.shape[1] / 2, max_loc[1] + target.shape[0] / 2
# 打开微信并使其最大化
def open_wechat():
pyautogui.hotkey('win', 'd')
file = os.popen(wechat_path)
file.close()
wechat_window.maximize()
# 截图整个窗口并保存
def screenshot():
x1 = wechat_window.left
y1 = wechat_window.top
x2 = wechat_window.left + wechat_window.width
y2 = wechat_window.top + wechat_window.height
template = ImageGrab.grab(bbox=(x1, y1, x2, y2))
if template:
template.save(path + '/image/' + 'template.png')
# 搜索目标
def search_target():
coord = find_img(searchBox_path, template_path)
pyautogui.click(coord)
pyperclip.copy(target_nickname)
pyautogui.hotkey('ctrl', 'v')
pyautogui.press('enter')
# 截图微信聊天区域并保存
def get_chat_frame():
x1 = wechat_window.left + 270
y1 = wechat_window.top + 70
x2 = wechat_window.left + wechat_window.width
y2 = wechat_window.top + wechat_window.height - 150
chat_frame = ImageGrab.grab(bbox=(x1, y1, x2, y2))
if chat_frame:
chat_frame.save(path + '/image/' + 'chatFrame.png')
# PCR获取聊天框中的消息
def get_message():
data_str = createRequest(chatFrame_path)
data = json.loads(data_str)
extracted_data = extract_boundingbox_and_text(data)
classified_data = classify_messages(extracted_data)
for item in classified_data:
type_desc = {
1: "己方消息",
2: "对方消息",
3: "其他消息"
}.get(item['type'], "未知")
print(f"{type_desc}: {item['text']}")
if classified_data[-1]['type'] == 2:
reply_content = ai.get_ai_reply(classified_data)
send_message(reply_content)
else:
print('对方暂时没有发送新消息')
# 从OCR识别结果中提取坐标(boundingBox)和文本(text)
def extract_boundingbox_and_text(data):
results = []
regions = data.get('Result', {}).get('regions', [])
for region in regions:
lines = region.get('lines', [])
for line in lines:
boundingBox = line.get('boundingBox', '')
text = line.get('text', '')
if boundingBox and text:
results.append({
'boundingBox': boundingBox,
'text': text
})
return results
# 解析boundingBox字符串,返回用于比较的坐标
def parse_bounding_box(bounding_box: str) -> tuple:
coords = [int(coord) for coord in bounding_box.split(',')]
x1 = coords[0] # 左上角x坐标
x2 = coords[2] # 右上角x坐标
return x1, x2
# 根据坐标分类消息
def classify_messages(data: List[Dict[str, Any]], tolerance: int = 200) -> List[Dict[str, Any]]:
if not data:
return data
# 找出所有x1的最小值和x2的最大值
x1_values = []
x2_values = []
for item in data:
x1, x2 = parse_bounding_box(item['boundingBox'])
x1_values.append(x1)
x2_values.append(x2)
min_x1 = min(x1_values)
max_x2 = max(x2_values)
print(f'用于做比较的坐标值: min_x1: {min_x1}, max_x2: {max_x2},当前误差阈值: {tolerance}')
# 分类统计
stats = {1: 0, 2: 0, 3: 0}
# 为每条数据添加type字段
result = []
for item in data:
new_item = item.copy()
x1, x2 = parse_bounding_box(item['boundingBox'])
# 判断消息类型
if abs(x2 - max_x2) <= tolerance:
new_item['type'] = 1 # 己方消息
stats[1] += 1
elif abs(x1 - min_x1) <= tolerance:
new_item['type'] = 2 # 对方消息
stats[2] += 1
else:
new_item['type'] = 3 # 其他消息
stats[3] += 1
result.append(new_item)
return result
# 发送消息
def send_message(message):
coord = find_img(dialogBox_path, template_path)
pyautogui.click(coord)
pyperclip.copy(message)
pyautogui.hotkey('ctrl', 'v')
pyautogui.press('enter')
# 主函数
def main():
open_wechat()
time.sleep(1)
screenshot()
search_target()
time.sleep(1)
get_chat_frame()
get_message()
if __name__ == "__main__":
wechat_path = 'D:\\Weixin\\Weixin.exe'
wechat_window = pygetwindow.getWindowsWithTitle('微信')[0]
target_nickname = '聊天名称'
path = os.getcwd().replace('\\', '/')
template_path = path + '/image/' + 'template.png'
searchBox_path = path + '/image/' + 'searchBox.png'
dialogBox_path = path + '/image/' + 'dialogBox.png'
chatFrame_path = path + '/image/' + 'chatFrame.png'
ai = AI.AI.DeepSeekBot()
main()
结束语
从旧工具的失效到新思路的诞生,这一过程让我深刻体会到技术探索的魅力与挑战。以 OCR 技术为切入点,重新构建微信 AI 机器人的逻辑架构,犹如在未知的领域中开辟一条新路。前方或许还会有更多的难题等待着我,但我不会退缩。我将秉持着对技术的热爱与执着,不断深入研究,在实践中积累经验,在当下AI纵横的环境中绽放出独特的光彩。
该工具完全模拟人为操作,不存在破解、注入等违法操作,正常使用下不会导致封号。
本文仅做技术原理探讨,请勿直接用于生产环境或违反微信《软件许可协议》的场景。
更多推荐


所有评论(0)