From dea993b57d529889df2000ee98e8b11cf061d7f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=81=BC=E7=9C=BC=E8=80=85?= <821986597@qq.com> Date: Mon, 3 Jun 2024 12:15:05 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BA=86=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E9=A2=9C=E8=89=B2=E5=BD=A2=E7=8A=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 55 +++++++++++++++++++++++++++++++++++-------------- utils/consts.py | 13 +++++++++++- utils/tools.py | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 16 deletions(-) diff --git a/main.py b/main.py index 90a4449..6bfac8d 100644 --- a/main.py +++ b/main.py @@ -1,20 +1,11 @@ import asyncio from api.qinglong import QlApi from config import ( - slide_difference, - slide_x_position, - slide_y_position, auto_move, qinglong_data, user_datas, jd_login_url, auto_shape_recognition, - backend_top_left_x, - backend_top_left_y, - small_img_top_left_x, - small_img_top_left_y, - small_img_bottom_right_x, - small_img_bottom_right_y ) from loguru import logger import time @@ -22,7 +13,7 @@ from playwright.async_api import Playwright, async_playwright import random import traceback from typing import Union -from utils.consts import supported_types +from utils.consts import supported_types, supported_colors from utils.tools import ( base_move, get_img_bytes, @@ -33,6 +24,7 @@ from utils.tools import ( get_word, save_screenshot_img, get_shape_location_by_type, + get_shape_location_by_color, click_by_autogui ) @@ -46,6 +38,11 @@ async def auto_move_slide(page, retry_times: int=2): """ 自动识别移动滑块验证码 """ + from config import ( + slide_difference, + slide_x_position, + slide_y_position + ) for i in range(retry_times): logger.info(f'第{i}次尝试自动移动滑块中...') try: @@ -70,6 +67,14 @@ async def auto_move_slide(page, retry_times: int=2): async def auto_shape(page, retry_times: int=5): + from config import ( + backend_top_left_x, + backend_top_left_y, + small_img_top_left_x, + small_img_top_left_y, + small_img_bottom_right_x, + small_img_bottom_right_y + ) ocr = get_ocr(beta=True) """ 自动识别滑块验证码 @@ -101,11 +106,31 @@ async def auto_shape(page, retry_times: int=5): word = get_word(ocr, small_img_path) if word.find('色') > 0: - logger.info(f'不支持颜色,刷新中......') - # 刷新 - await refresh_button.click() - await asyncio.sleep(random.random() * 2) - continue + target_color = word.split('请选出图中')[1].split('的图形')[0] + if target_color in supported_colors: + logger.info(f'正在点击中......') + # 获取点的中心点 + center_x, center_y = get_shape_location_by_color(background_img_path, target_color) + if center_x is None and center_y is None: + logger.info(f'识别失败,刷新中......') + await refresh_button.click() + continue + # 得到网页上的中心点 + x, y = backend_top_left_x + center_x ,backend_top_left_y + center_y + # 点击图片 + click_by_autogui(x, y) + await asyncio.sleep(random.random() * 3) + # 点击确定 + await button.click() + await asyncio.sleep(3) + continue + else: + logger.info(f'不支持该颜色,刷新中......') + # 刷新 + await refresh_button.click() + await asyncio.sleep(random.random() * 2) + continue + else: type = word.split('请选出图中的')[1] if type in supported_types: diff --git a/utils/consts.py b/utils/consts.py index 4dc1916..85ec9c9 100644 --- a/utils/consts.py +++ b/utils/consts.py @@ -6,4 +6,15 @@ supported_types = [ "六边形", "圆形", "梯形" -] \ No newline at end of file +] +# 定义了支持的每种颜色的 HSV 范围 +supported_colors = { + '紫色': ([125, 50, 50], [145, 255, 255]), + '灰色': ([0, 0, 50], [180, 50, 255]), + '粉色': ([160, 50, 50], [180, 255, 255]), + '蓝色': ([100, 50, 50], [130, 255, 255]), + '绿色': ([40, 50, 50], [80, 255, 255]), + '橙色': ([10, 50, 50], [25, 255, 255]), + '黄色': ([25, 50, 50], [35, 255, 255]), + '红色': ([0, 50, 50], [10, 255, 255]) +} \ No newline at end of file diff --git a/utils/tools.py b/utils/tools.py index 99abaf6..57d8d87 100644 --- a/utils/tools.py +++ b/utils/tools.py @@ -2,12 +2,15 @@ import base64 import cv2 import ddddocr import io +import numpy as np import pyautogui import random import os from PIL import Image, ImageGrab import re import time +from utils.consts import supported_colors + def get_tmp_dir(tmp_dir:str = './tmp'): # 检查并创建 tmp 目录(如果不存在) @@ -211,6 +214,42 @@ def get_shape_location_by_type(img_path, type: str): return None, None +def get_shape_location_by_color(img_path, target_color): + """ + 根据颜色获取指定形状在图片中的坐标 + """ + + # 检查目标颜色是否在定义的颜色范围内 + if target_color not in supported_colors: + raise ValueError(f"Color {target_color} is not defined in the color ranges.") + + # 读取图像 + image = cv2.imread(img_path) + # 读取图像并转换为 HSV 色彩空间。 + hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) + + # 获取目标颜色的范围 + lower, upper = supported_colors[target_color] + lower = np.array(lower, dtype="uint8") + upper = np.array(upper, dtype="uint8") + + # 创建掩码并找到轮廓 + mask = cv2.inRange(hsv_image, lower, upper) + contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) + + # 遍历轮廓并在中心点画点 + for contour in contours: + # 过滤掉太小的区域 + if cv2.contourArea(contour) > 100: + M = cv2.moments(contour) + if M["m00"] != 0: + cX = int(M["m10"] / M["m00"]) + cY = int(M["m01"] / M["m00"]) + return cX, cY + + return None, None + + def click_by_autogui(x, y): """ 点击指定坐标的元素