AutoPercenty/edit/options.py

146 lines
8.4 KiB
Python

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import time
from edit.action_elements import click_element, return_element
from ai.deepl import trans
from ai.compare import find_most_similar_image_by_one
import re
import logging
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
def modify_option_page(driver, original_img):
# 옵션 탭으로 이동
logger.debug("옵션탭으로 이동")
option_tab_XPATH = "//div[@id='rc-tabs-0-tab-1']"
click_element(driver, 'XPATH', option_tab_XPATH, 10, 'js')
logger.debug("옵션탭으로 이동 완료")
logger.debug("페이지 로딩 대기")
time.sleep(2) # 페이지 로딩 대기.
# 옵션타입 갯수 체크
# 옵션타입2가 존재할 경우 옵션타입2의 옵션갯수에 따라 (1개면 작업하지 않고, 2개이상일 경우 작업)
# 일단 보류
logger.debug("옵션타입 체크")
option_type_1_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[1]/div/div/div/span/div/div/span"
# 옵션타입이 1개일 경우 옵션타입2를 가져올 경우 오류발생할 것. 적절한 예외처리필요
option_type_2_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[2]/div/div/div/span/div/div/span"
option_type_3_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[3]/div/div/div/span/div/div/span"
option_type1 = return_element(driver, 'XPATH', option_type_1_xpath, 10)
logger.debug(f"옵션 타입 : {option_type1.text}")
# 현재 전체 옵션갯수 가져오기
# 가져온 옵션갯수에 따라, 2개이하면 수정하지 않고, 3개이상일 경우 이미지 유사도에 따라 선택
logger.debug("옵션갯수 가져오기")
option_num_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[5]/div/div/label/span[2]"
option_num_element = return_element(driver, 'XPATH', option_num_xpath, 10)
option_number = int(re.search(r'\d+', option_num_element.text).group())
# 가격 낮은 순으로 정렬
logger.debug("가격 낮은 순으로 정렬")
low_price_order_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[5]/div/div[3]/button/span"
click_element(driver, 'XPATH', low_price_order_xpath, 10, 'js')
# 이미지 비교
logger.debug("이미지 비교로 유사도 판단 후 옵션 선택")
# 옵션 이미지 URL을 저장할 리스트 초기화
option_images_urls = []
selected_option_indexes = []
for i in range(1, option_number + 1):
# 옵션 이미지의 XPath 경로 동적 생성
opt_img_xpath = f"//li[{i}]/div/div/div/div[2]/div/img"
try:
# 해당 XPath를 이용하여 웹 요소 찾기
opt_img_element = driver.find_element(By.XPATH, opt_img_xpath)
except Exception as e:
logger.debug(f"옵션 이미지 xpath를 찾을 수 없음 {e}")
opt_img_element = None
# 옵션이미지가 없을 경우 처리
if not opt_img_element:
logger.debug(f"{i}번째 옵션이미지가 없음")
# 아래의 2가지 상황에 맞추어 추가코드 필요
# 1. 전체 옵션의 이미지가 없는 경우 처리
# 2. 일부 옵션만 이미지가 없는 경우 처리
else:
# 웹 요소의 src 속성에서 이미지 URL 추출
img_url = opt_img_element.get_attribute('src')
# 추출한 이미지 URL을 리스트에 추가
option_images_urls.append(img_url)
# 유사도 비교로 적합한 이미지를 가진 옵션번호 저장
similarity = find_most_similar_image_by_one(original_img, img_url)
if similarity > 0.6:
selected_option_indexes.append(i)
logger.debug(f"옵션번호 {i}번이 이미지 유사도 {similarity}로 선택되었습니다.")
# # 선택된 옵션인덱스로 실제 옵션 체크
# # 옵션타입1의 옵션전체 선택&해제 버튼 xpath=(//input[@type='checkbox'])[22]
# # 옵션타입1의 1번 옵션 선택&해제 버튼 xpath=(//input[@type='checkbox'])[23]
# # 옵션타입1의 2번 옵션 선택&해제 버튼 xpath=(//input[@type='checkbox'])[24]
# # 주의점은 해당 옵션을 체크해제할 경우 이미지 주소를 가져올 수 없으므로, 체크 해제 전 모든 옵션에 해당하는 이미지 주소를 가져올 것.
# # 만약 이미지 주소가 none이거나 없으면 이미지 비교를 하지말고 옵션명으로 비교할 것.
logger.debug("옵션갯수 다시 가져오기")
selected_option_num_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[5]/div/div/label/span[2]"
selected_option_num_element = return_element(driver, 'XPATH', selected_option_num_xpath, 10)
selected_options_num = int(re.search(r'\d+', selected_option_num_element.text).group())
logger.debug("선택된 옵션 인덱스로 옵션박스 체크 실행")
all_checkbox_xpath=("//input[@type='checkbox'])[22]") # 전체옵션 체크해제를 위한 준비
# all_checkbox_xpath="//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[5]/div/div/label/span/input"
# selected_options_num = len(selected_option_indexes)
selected_options_num = selected_option_indexes
max_options_num = min(7, selected_options_num)
if option_number > 2: # 선택가능한 옵션갯수가 2개이하일 경우 모든옵션을 선택하기 위함.
logger.debug("전체옵션 선택해제 실행")
click_element(driver, 'XPATH', all_checkbox_xpath, 10, 'js')
for i in range(1, max_options_num + 1): # 최대 선택가능한 옵션은 아무리 많아도 (7개 또는 selected_options_num 중 작은 숫자) 까지만
selected_option_number = selected_option_indexes[i]
option_checkbox_xpath = f"(//input[@type='checkbox'])[{22 + selected_option_number}]"
logger.debug(f"{i}번째 옵션 체크")
click_element(driver,'XPATH', option_checkbox_xpath, 10, 'js')
logger.debug("선택된 옵션명 DeepL로 번역 후 새로운 옵션명 입력")
logger.debug("선택된 옵션갯수 새로 가져오기")
selected_option_num_element = return_element(driver, 'XPATH', option_num_xpath, 10)
selected_option_number = int(re.search(r'\d+', selected_option_num_element).group())
for i in range(1, selected_option_number + 1):
# 원본 옵션이름의 XPath 경로 동적 생성으로 원본옵션명을 번역 생성
ori_optionName_xpath = f"/html/body/div[28]/div/div[3]/div/div[2]/div[1]/div[1]/div[2]/div/div/div[2]/div/div[1]/div/div/div[2]/div/div/div[6]/div[1]/div/div/ul/li[{i}]/div/div[1]/div/div[3]/div[3]/span"
ori_optionName_element = driver.find_element(By.XPATH, ori_optionName_xpath)
ori_optionName = ori_optionName_element.get_attribute('text')
trans_option_name = trans(ori_optionName)
# 옵션이름입력칸의 XPath 경로 동적 생성으로 번역된 옵션명을 새로 입력
optionName_input_xpath = f"//li[{i}]/div/div/div/div[3]/div[2]/div/span/input"
optionName_input_element = driver.find_element(By.XPATH, optionName_input_xpath)
optionName_input_element.setText(trans_option_name)
logger.debug("옵션선택과 옵션명 수정 완료 후 옵션명 정리")
# A-Z
# xpath=//span[contains(.,'A-Z')]
# xpath=//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div/div/div/div/button/span
# 1-99
# xpath=//span[contains(.,'1-99')]
# xpath=//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div/div/div/div[2]/button/span
# 빈칸제거
# xpath=//span[contains(.,'빈칸 제거')]
# xpath=//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div/div/div/div[2]/div/div/div[4]/div/div/div/div[3]/button/span