import cv2
import easyocr
import numpy as np
import warnings
import subprocess
import time
import os
warnings.filterwarnings("ignore")
LIST_X1, LIST_X2 = 30, 400
LIST_Y1, LIST_Y2 = 80, 1000
OUTPUT_IMG_PATH = "/home/nick/workspace/RPA/real_time_ocr_verify.png"
SCREENSHOT_PATH = "/home/nick/workspace/RPA/real_time_screenshot.png"
DRAG_OFFSET = 100
COPY_DELAY = 3
reader = easyocr.Reader(
lang_list=['ch_sim', 'en'],
gpu=False,
verbose=False,
model_storage_directory="/home/nick/.EasyOCR/model"
)
def capture_screen():
"""截取整个屏幕并返回图片"""
subprocess.run(["scrot", SCREENSHOT_PATH], check=True, capture_output=True)
img = cv2.imread(SCREENSHOT_PATH)
if img is None:
raise Exception("❌ 无法读取截屏图片")
print(f"✅ 已截取屏幕:{SCREENSHOT_PATH}")
return img
def ocr_list_coordinates(img):
"""识别列表项中心坐标,返回坐标列表+带标记的验证图"""
crop_img = img[LIST_Y1:LIST_Y2, LIST_X1:LIST_X2]
gray = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
result = reader.readtext(gray, detail=1)
list_coords = []
img_verify = img.copy()
for (bbox, text, conf) in result:
text = text.strip()
if all(c == '?' for c in text) or len(text) < 2 or text.count('?')/len(text) > 0.5:
continue
center_x = int((bbox[0][0] + bbox[2][0])/2 + LIST_X1)
center_y = int((bbox[0][1] + bbox[2][1])/2 + LIST_Y1)
list_coords.append((center_x, center_y))
cv2.circle(img_verify, (center_x, center_y), 5, (0,0,255), -1)
cv2.putText(img_verify, f"({center_x},{center_y})",
(center_x+10, center_y), cv2.FONT_HERSHEY_SIMPLEX,
0.4, (0,0,255), 1)
cv2.imwrite(OUTPUT_IMG_PATH, img_verify)
print(f"✅ 验证图已保存:{OUTPUT_IMG_PATH}")
print(f"✅ 识别到 {len(list_coords)} 个列表项")
return list_coords
def get_clipboard_text():
"""读取系统剪贴板内容"""
try:
result = subprocess.run(["xclip", "-o", "-selection", "clipboard"],
capture_output=True, text=True, check=True)
return result.stdout.strip()
except:
return ""
def copy_list_item_text(center_coords):
"""批量拷贝列表项文字"""
print(f"\n========================================")
print(f"📋 {COPY_DELAY}秒后开始拷贝,请立刻切回目标窗口!")
print(f"========================================")
time.sleep(COPY_DELAY)
copied_results = []
for idx, (x, y) in enumerate(center_coords, 1):
print(f"\n🔹 处理列表项 {idx}(坐标:{x},{y}):")
subprocess.run(["xdotool", "mousemove", str(x - DRAG_OFFSET), str(y)])
time.sleep(0.2)
subprocess.run(["xdotool", "mousedown", "1"])
time.sleep(0.2)
subprocess.run(["xdotool", "mousemove", str(x + DRAG_OFFSET), str(y)])
time.sleep(0.2)
subprocess.run(["xdotool", "mouseup", "1"])
time.sleep(0.2)
subprocess.run(["xdotool", "key", "ctrl+c"])
time.sleep(0.2)
text = get_clipboard_text()
copied_results.append({
"index": idx,
"coords": (x, y),
"text": text
})
if text:
print(f"✅ 拷贝成功:{text}")
else:
print(f"❌ 拷贝失败")
return copied_results
def main():
try:
print("========================================")
print("📸 按回车键触发实时截屏(确保目标窗口在前台)")
print("========================================")
input()
screen_img = capture_screen()
list_coords = ocr_list_coordinates(screen_img)
if not list_coords:
print("❌ 未识别到任何列表项")
return
copy_list_item_text(list_coords)
print("\n🎉 所有操作完成!验证图可查看坐标标记,拷贝结果已输出。")
except Exception as e:
print(f"\n❌ 执行失败:{str(e)}")
if __name__ == "__main__":
main()