AutoPercenty3/test/img_test.py

298 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import pyautogui
import time
import os
import subprocess
import win32gui, win32con, win32process
import pyscreeze
class WhaleTranslator:
def __init__(self, logger, error_image_filenames=['fail_translated1.png', 'fail_translated2.png'], pixel_check_interval=0.1, secret_mode=True, timeout=20, color_tolerance=20):
self.logger = logger
self.error_image_paths = [os.path.join(os.path.dirname(__file__), filename) for filename in error_image_filenames]
self.page_loading_icon_path = os.path.join(os.path.dirname(__file__), 'page_loading.png')
self.translating_image_path = os.path.join(os.path.dirname(__file__), 'translating.png')
# self.translating_image_path = os.path.join(os.path.dirname(__file__), 'src', 'img', 'translating.png')
self.pixel_check_interval = pixel_check_interval
self.whale_window_name = "새 시크릿 탭 - Whale" if secret_mode else "새 탭 - Whale"
self.whale_pid = None
self.timeout = timeout # 번역 성공 여부를 판단하기 위한 시간 제한 설정
self.color_tolerance = color_tolerance # 색상 허용 오차
self.colors = {'before': None, 'during': None, 'after': None} # 색상 기록
self.whale_rect = None
def start_whale_browser(self, url):
whale_path = r"C:\\Program Files\\Naver\\Naver Whale\\Application\\whale.exe"
process = subprocess.Popen([whale_path, '--incognito'])
time.sleep(2)
self.whale_pid = process.pid
self.logger.debug(f"Whale 브라우저 실행, PID: {self.whale_pid}")
hwnd = self.find_whale_window()
if hwnd:
self.set_window_position(hwnd, 1, 1, 1280, 720) # 위치 (100, 100), 크기 (1280x720)
self.update_whale_rect()
if hwnd:
win32gui.SetForegroundWindow(hwnd)
pyautogui.hotkey('ctrl', 'l')
time.sleep(0.5)
pyautogui.typewrite(url)
pyautogui.press('enter')
time.sleep(2)
size = self.get_whale_window_title()
# # 페이지 로딩 완료 대기
# self.wait_for_loading_icon_to_disappear()
self.move_mouse_to_center() # 마우스 중앙으로 이동
time.sleep(0.5) # 마우스 이동 후 대기
original_color = self.get_mouse_position_color() # 현재 색상 가져오기
self.colors['before'] = original_color
self.logger.debug(f"번역 전 색상: {original_color}")
# 우클릭 및 번역 시작
pyautogui.rightClick()
time.sleep(1)
pyautogui.press('r')
# # 번역 시작 감지 (translating.png 확인)
# if self.is_translating():
# self.logger.debug("번역 시작 감지 ('translating.png' 발견)")
# 번역 중 색상 지속 확인
result = self.check_translation_by_color_change()
if result == "success":
self.logger.debug(f"URL: {url} - 번역이 성공적으로 완료되었습니다!")
elif result == "error":
self.logger.debug(f"URL: {url} - 번역에 실패했습니다.")
else:
self.logger.debug(f"URL: {url} - 번역 상태를 확인하지 못했습니다.")
# 최종 색상 출력
self.logger.debug(f"URL: {url} - 번역 중 색상: {self.colors['during']}")
self.logger.debug(f"URL: {url} - 번역 후 색상: {self.colors['after']}")
def wait_for_loading_icon_to_disappear(self, max_wait=20):
"""
로딩 아이콘이 화면에서 사라질 때까지 대기합니다.
max_wait: 최대 대기 시간 (초)
"""
start_time = time.time()
while time.time() - start_time < max_wait:
try:
# 화면에서 아이콘 위치 확인 시도
icon_location = self.find_image_with_confidence(self.page_loading_icon_path, confidence=0.9)
if icon_location:
self.logger.debug("페이지 로딩 중...")
time.sleep(0.5) # 간격을 두고 다시 확인
except pyautogui.ImageNotFoundException as e:
# 아이콘이 화면에 없으면 로딩 완료로 간주
# self.logger.debug(f"페이지 로딩이 완료되었습니다. {e}", exc_info=True)
self.logger.debug(f"페이지 로딩이 완료되었습니다.")
return True # 로딩 완료
self.logger.debug("로딩 완료 대기 시간이 초과되었습니다.")
return False
def find_image_with_confidence(self, image_path, confidence=0.8):
"""이미지를 찾을 때 highest confidence 값을 로그로 출력하는 메서드"""
if self.whale_rect:
# 웨일 창의 크기를 region으로 설정
region = (self.whale_rect[0], self.whale_rect[1],
self.whale_rect[2] - self.whale_rect[0],
self.whale_rect[3] - self.whale_rect[1])
self.logger.debug(f"이미지를 찾을 영역: {region}")
try:
# locateOnScreen 시도
result = pyscreeze.locateOnScreen(image_path, confidence=confidence, region=region)
if result:
self.logger.debug(f"이미지를 찾았습니다: {image_path}")
return result
else:
raise pyscreeze.ImageNotFoundException("Could not locate the image")
except pyscreeze.ImageNotFoundException as e:
# 'Could not locate the image' 메시지 발생 시 최고 confidence 값 로그 출력
if hasattr(e, 'args') and 'highest confidence' in str(e.args[0]):
self.logger.error(f"{image_path} 이미지를 찾지 못했습니다만 유사한 부분을 찾았습니다. : [{e.args[0]}]")
else:
self.logger.error(f"{image_path}이미지를 찾지 못했습니다. 이미지와 유사한 부분을 찾지 못했습니다.")
return None
def is_translating(self):
"""translating.png가 화면에 나타나는지 확인하여 번역 시작 여부를 판단"""
try:
# translating_location = pyautogui.locateOnScreen(self.translating_image_path, confidence=0.8)
translating_location = self.find_image_with_confidence(self.translating_image_path, confidence=0.4)
if translating_location:
return True
except pyautogui.ImageNotFoundException as e:
self.logger.debug(f"'translating.png'를 찾지 못했습니다. : {e}", exc_info=True)
return False
def update_whale_rect(self):
"""웨일 창의 위치 및 크기 rect를 업데이트"""
if self.whale_hwnd:
self.whale_rect = win32gui.GetWindowRect(self.whale_hwnd)
self.logger.debug(f"웨일 창 크기 및 위치 저장: {self.whale_rect}")
def get_whale_window_title(self):
"""
현재 활성화된 웨일 창의 이름을 가져옵니다.
제목에서 이미지의 해상도를 확인한 후, 일정 크기 이하인 경우 작업을 패스하도록 처리합니다.
"""
# hwnd = self.find_whale_window() # 웨일 창 핸들 가져오기
if self.whale_hwnd:
window_title = win32gui.GetWindowText(self.whale_hwnd)
self.logger.debug(f"현재 웨일 창의 제목: {window_title}")
# 해상도를 추출하기 위해 제목에서 괄호 안의 (숫자×숫자) 부분을 찾음
import re
match = re.search(r"\((\d+)×(\d+)\)", window_title)
if match:
width = int(match.group(1))
height = int(match.group(2))
self.logger.debug(f"이미지 해상도: {width}×{height}")
# 해상도가 기준보다 작은 경우 패스
if width < 300 or height < 200:
self.logger.debug(f"이미지 해상도가 너무 작습니다. ({width}×{height}), 작업을 패스합니다.")
return False # 작업을 수행하지 않음
return True # 작업을 계속 진행
else:
self.logger.error("이미지 해상도를 가져오지 못했습니다.")
return False
self.logger.error("웨일 창을 찾을 수 없습니다.")
return False
def find_whale_window(self):
"""웨일 창을 제목을 기준으로 찾는 메서드"""
def callback(hwnd, extra):
if win32gui.IsWindowVisible(hwnd):
title = win32gui.GetWindowText(hwnd)
if self.whale_window_name in title:
extra.append(hwnd)
hwnd_list = []
win32gui.EnumWindows(callback, hwnd_list)
if hwnd_list:
self.whale_hwnd = hwnd_list[0]
self.logger.debug(f"웨일 창을 찾았습니다: {self.whale_hwnd}")
self.update_whale_rect()
return self.whale_hwnd
else:
self.logger.debug("웨일 창을 찾지 못했습니다.")
return None
def set_window_position(self, hwnd, x, y, width, height):
"""지정된 위치와 크기로 창을 조정"""
win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)
win32gui.SetWindowPos(hwnd, None, x, y, width, height, win32con.SWP_NOZORDER | win32con.SWP_NOACTIVATE)
self.logger.debug(f"창 위치 및 크기 설정: 위치({x}, {y}), 크기({width}x{height})")
def move_mouse_to_center(self):
"""웨일 브라우저 창의 중앙으로 마우스 커서를 이동"""
if self.whale_rect:
center_x = (self.whale_rect[0] + self.whale_rect[2]) // 2 # 가로 중앙 계산
center_y = (self.whale_rect[1] + self.whale_rect[3]) // 2 # 세로 중앙 계산
center_y = center_y + 50
pyautogui.moveTo(center_x, center_y)
self.logger.debug(f"마우스 커서를 창 중앙으로 이동: ({center_x}, {center_y})")
else:
self.logger.error("웨일 창의 크기를 알 수 없습니다. 먼저 창을 찾으세요.")
def is_color_changed(self, current_color):
"""현재 색상이 변화했는지 확인 (필터 제거 여부)"""
if self.colors['during'] is None:
self.colors['during'] = current_color
return not self.is_similar_color(current_color, self.colors['during'])
def check_translation_by_color_change(self):
start_time = time.time()
# 번역 시작 감지 (translating.png 확인)
while time.time() - start_time < self.timeout:
current_color = self.get_mouse_position_color()
self.logger.debug(f"현재 색상: {current_color}")
# 필터가 사라져서 색상이 변했는지 확인
if self.is_color_changed(current_color):
self.colors['after'] = current_color
self.logger.debug("색상 변화 감지 (필터 제거됨)")
# translating.png가 여전히 존재하는지 확인하여 번역 성공 여부 판단
result = self.find_image_with_confidence(self.translating_image_path, confidence=0.4)
if result:
return "success"
else:
return "error"
else:
# 번역 실패 이미지 확인
if self.is_translation_failed():
self.colors['after'] = current_color
return "error"
time.sleep(self.pixel_check_interval)
# 타임아웃 발생 시 translating.png 여부로 번역 성공/실패 판단
self.colors['after'] = current_color
result = self.find_image_with_confidence(self.translating_image_path, confidence=0.4)
if result:
self.logger.debug("번역 성공으로 간주 (타임아웃 후 translating.png 존재)")
return "success"
else:
self.logger.debug("번역 실패로 간주 (타임아웃 후 translating.png 없음)")
return "error"
def is_similar_color(self, color1, color2):
"""색상이 유사한지 확인 (허용 오차 적용)"""
r_diff = abs(color1[0] - color2[0])
g_diff = abs(color1[1] - color2[1])
b_diff = abs(color1[2] - color2[2])
return r_diff < self.color_tolerance and g_diff < self.color_tolerance and b_diff < self.color_tolerance
def get_mouse_position_color(self):
x, y = pyautogui.position()
return pyautogui.pixel(x, y)
def is_translation_failed(self):
"""번역 실패 이미지 확인"""
for image_path in self.error_image_paths:
result = self.find_image_with_confidence(image_path, confidence=0.8)
if result:
self.logger.error(f"번역 실패: '{os.path.basename(image_path)}' 메시지가 감지되었습니다.")
return True
return False
# 예제 사용법
import logging
# 로거 설정
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
# 클래스 인스턴스 생성 및 브라우저 실행 후 번역 상태 확인
translator = WhaleTranslator(logger, ['fail_translated1.png', 'fail_translated2.png'])
# 브라우저 실행 후 URL로 이동 및 번역 성공 여부 확인
translator.start_whale_browser('https://img.alicdn.com/imgextra/i3/350475995/O1CN01uFwQ9v1u9kwOuU78C-350475995.png_Q75.jpg')
translator.start_whale_browser("https://file.percenty.co.kr/public/652bed8e865b1f32ea62bf1f/products/66ff967773994c46d388bb36/82d07178-ae60-49f7-a489-e02801ff7b06.jpg")
translator.start_whale_browser('https://img.alicdn.com/imgextra/i4/735691568/O1CN01sRUYqb1NSBuefMBlw_!!735691568.jpg_Q75.jpg')
translator.start_whale_browser('https://img.alicdn.com/imgextra/i4/1773313923/O1CN01VMRs1Z1eqmfYSXQDu_!!1773313923.jpg_Q75.jpg')