147 lines
8.4 KiB
Python
147 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)
|
|
similarity = 0.7
|
|
|
|
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
|