基于UI自动化的51vv聊天信息获取方案
。既然51vv只有客户端没有网页版,我们可以用UI自动化方案来模拟人工操作。
🖥️ 方案1:Python + OpenCV图像识别(免Hook)
这是最安全的方式,完全模拟真人操作,不触碰内存或网络层:
import cv2
import numpy as np
import pyautogui
import pytesseract
import time
import os
from PIL import Image
import win32gui
import win32con
import win32api
class VVMonitor:
def __init__(self, window_title="51vv"):
self.window_title = window_title
self.hwnd = None
self.chat_log = []
def find_window(self):
"""找到51vv聊天窗口"""
def callback(hwnd, windows):
if win32gui.IsWindowVisible(hwnd) and self.window_title in win32gui.GetWindowText(hwnd):
windows.append(hwnd)
return True
windows = []
win32gui.EnumWindows(callback, windows)
if windows:
self.hwnd = windows[0]
return True
return False
def capture_chat_area(self):
"""截取聊天区域"""
if not self.hwnd:
return None
# 获取窗口位置和大小
rect = win32gui.GetWindowRect(self.hwnd)
x, y, w, h = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]
# 聊天区域大致位置(需要根据实际窗口调整)
chat_x = x + int(w * 0.6) # 聊天区域可能在右侧
chat_y = y + int(h * 0.2)
chat_w = int(w * 0.35)
chat_h = int(h * 0.6)
# 截图
screenshot = pyautogui.screenshot(region=(chat_x, chat_y, chat_w, chat_h))
return np.array(screenshot)
def extract_text_from_image(self, image):
"""OCR识别图片中的文字"""
# 转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 图像预处理,提高OCR准确率
_, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)
# OCR识别
text = pytesseract.image_to_string(thresh, lang='chi_sim') # 中文语言包
return text
def parse_chat_messages(self, text):
"""解析聊天消息,提取用户ID和内容"""
lines = text.split('\n')
for line in lines:
# 假设消息格式是 "[ID] 用户名: 消息内容"
# 需要根据实际显示格式调整正则表达式
import re
match = re.search(r'\[(\d+)\]\s*([^:]+):\s*(.+)', line)
if match:
user_id = match.group(1)
username = match.group(2)
content = match.group(3)
if content not in [msg['content'] for msg in self.chat_log[-10:]]:
message = {
'user_id': user_id,
'username': username,
'content': content,
'time': time.time()
}
self.chat_log.append(message)
print(f"[{user_id}] {username}: {content}")
return message
return None
def monitor_loop(self, interval=2):
"""持续监控"""
if not self.find_window():
print("未找到51vv窗口")
return
print("开始监控聊天消息...")
last_text = ""
while True:
try:
# 截图并识别
chat_img = self.capture_chat_area()
if chat_img is not None:
text = self.extract_text_from_image(chat_img)
# 如果文本有变化,说明有新消息
if text != last_text:
self.parse_chat_messages(text)
last_text = text
time.sleep(interval)
except KeyboardInterrupt:
print("监控结束")
break
except Exception as e:
print(f"错误: {e}")
time.sleep(5)🖱️ 方案2:PyAutoGUI + 剪贴板操作(更精准)
利用复制粘贴功能获取精准文本:
import pyautogui
import pyperclip
import time
import re
class VVChatMonitor:
def __init__(self):
self.messages = []
def select_and_copy(self, x, y):
"""在指定位置点击并复制文本"""
# 移动到聊天区域
pyautogui.moveTo(x, y)
# 双击选中文本
pyautogui.doubleClick()
time.sleep(0.2)
# 右键复制
pyautogui.rightClick()
time.sleep(0.2)
# 需要根据右键菜单的实际位置调整
pyautogui.move(0, 40) # 向下移动到"复制"选项
pyautogui.click()
time.sleep(0.2)
# 获取剪贴板内容
return pyperclip.paste()
def scan_chat_area(self, start_x, start_y, end_x, end_y, step=20):
"""扫描聊天区域,逐行复制"""
messages = []
for y in range(start_y, end_y, step):
try:
text = self.select_and_copy(start_x + 10, y)
if text and self.is_valid_message(text):
messages.append(text)
except:
pass
return messages
def is_valid_message(self, text):
"""判断是否是有效的聊天消息"""
# 根据实际格式调整
patterns = [
r'\[\d+\]', # 包含[数字]
r'\d{4,10}', # 包含4-10位数字(可能是ID)
r'.{2,20}:', # 包含冒号(可能是用户名和内容的分隔)
]
return any(re.search(p, text) for p in patterns)
def monitor_realtime(self, chat_area_rect):
"""实时监控(需要找到聊天区域的最新消息位置)"""
last_message = ""
x, y, w, h = chat_area_rect
while True:
# 移动到聊天区域底部(最新消息)
latest_y = y + h - 30
text = self.select_and_copy(x + 50, latest_y)
if text and text != last_message:
print(f"新消息: {text}")
self.messages.append(text)
last_message = text
time.sleep(3)🔧 方案3:AutoHotkey + Python混合(最稳定)
AutoHotkey处理UI交互,Python处理数据分析:
AutoHotkey脚本 (vv_chat.ahk)
#Persistent
CoordMode, Mouse, Window
; 获取聊天文本的函数
GetChatText(x, y) {
MouseMove, x, y
Click, 2 ; 双击选中
Sleep, 100
Send, ^c ; 复制
Sleep, 100
return Clipboard
}
; 持续监控
Loop {
; 假设聊天区域底部位置
text := GetChatText(800, 500)
FileAppend, %text%`n, chat_log.txt
Sleep, 3000
}Python端处理
import time
import re
import subprocess
from pathlib import Path
class AHKChatProcessor:
def __init__(self):
self.ahk_process = None
self.log_file = Path("chat_log.txt")
def start_ahk_script(self, script_path):
"""启动AutoHotkey脚本"""
self.ahk_process = subprocess.Popen(["AutoHotkey.exe", script_path])
def process_log(self):
"""处理AutoHotkey生成的日志"""
while True:
if self.log_file.exists():
with open(self.log_file, 'r', encoding='utf-8') as f:
lines = f.readlines()
for line in lines[-10:]: # 只处理最新的10行
self.parse_chat_line(line)
time.sleep(2)
def parse_chat_line(self, line):
"""解析聊天行"""
# 根据实际格式调整
pattern = r'(\d{6,12})\s*([^:]+):\s*(.+)'
match = re.search(pattern, line)
if match:
user_id, username, content = match.groups()
print(f"用户 {username}({user_id}): {content}")
return {
'user_id': user_id,
'username': username,
'content': content,
'time': time.time()
}
return None📊 实际部署步骤
准备工作
# 安装必要的库 pip install opencv-python pytesseract pyautogui pyperclip pillow numpy # 安装Tesseract OCR(用于中文识别) # Windows: https://github.com/UB-Mannheim/tesseract/wiki # 需要下载中文语言包 chi_sim获取窗口坐标
# 先用这个脚本找出聊天区域坐标 import pyautogui import time print("将鼠标移到聊天区域左上角,5秒后获取坐标...") time.sleep(5) x1, y1 = pyautogui.position() print(f"左上角: ({x1}, {y1})") time.sleep(2) print("将鼠标移到聊天区域右下角,5秒后获取坐标...") time.sleep(5) x2, y2 = pyautogui.position() print(f"右下角: ({x2}, {y2})") print(f"聊天区域: x={x1}, y={y1}, w={x2-x1}, h={y2-y1}")- 根据实际界面调整参数
- 51vv的聊天区域位置可能因皮肤、窗口大小而异
- 消息格式可能是:
[用户ID] 昵称: 消息内容 - 或者:
时间 [ID] 昵称: 内容
⚠️ 注意事项
准确性限制
- OCR识别中文可能出错,特别是特殊字体
- 截图区域需要精确定位
- 动态滚动时可能漏掉消息
性能影响
- 频繁截图会占用CPU
- 建议设置2-5秒的监控间隔
稳定性
- 确保51vv窗口不被遮挡
- 避免鼠标键盘被其他操作干扰
💡 替代思路:模拟登录客户端
如果你想更稳定地获取数据,可以尝试:
# 用pywinauto控制客户端
from pywinauto.application import Application
app = Application().start(r"C:\Program Files\51vv\51vv.exe")
# 等待登录界面
# 自动输入账号密码
# 进入房间后抓取聊天控件文本这个方案需要逆向分析客户端的UI控件结构,但一旦成功,比图像识别更稳定。
最推荐方案1(OCR识别)或方案3(AutoHotkey+Python),因为它们在法律上最安全(只是模拟人工操作),并且能实现你的核心需求:获取公开的聊天内容和用户ID。