1
0
Fork 0
This commit is contained in:
R5600U_PC 2024-06-18 13:22:08 +09:00
parent d7228e3ecc
commit 429d815dd1
2 changed files with 408 additions and 36 deletions

View File

@ -12,6 +12,10 @@ from ai.deepl_with_playwright import trans_text, trans_list_text
import re
import logging
import tempfile
from img_trans.image_trans import image_trans
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
@ -48,41 +52,48 @@ def modify_option_page(driver, product_info, translator, login_info):
logger.debug("옵션타입 체크")
# 옵션 타입 처리
for i in range(1, 4): # 옵션 타입이 1부터 3까지 존재한다고 가정합니다.
option_type_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{i}]/div/div/div[2]/div/div/div[2]/div/span/input"
option_type = return_element(driver, 'XPATH', option_type_xpath, 3)
if option_type:
option_type_value = option_type.get_attribute('value')
options_info[f'option_type_{i}'] = {'options_name': option_type_value, 'options_count': 0, 'price_ranges': []}
logger.debug(f"옵션 타입 추가: {option_type_value}")
else:
logger.debug(f"{option_type_xpath} 요소를 찾을 수 없음.")
# # 옵션 타입 처리
# for i in range(1, 4): # 옵션 타입이 1부터 3까지 존재한다고 가정합니다.
# option_type_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{i}]/div/div/div[2]/div/div/div[2]/div/span/input"
# option_type = return_element(driver, 'XPATH', option_type_xpath, 3)
# if option_type:
# option_type_value = option_type.get_attribute('value')
# options_info[f'option_type_{i}'] = {'options_name': option_type_value, 'options_count': 0, 'price_ranges': []}
# logger.debug(f"옵션 타입 추가: {option_type_value}")
# else:
# logger.debug(f"{option_type_xpath} 요소를 찾을 수 없음.")
option_type_nums = sum(1 for key in options_info.keys() if key.startswith('option_type_'))
logger.debug(f"총 옵션 타입 수: {option_type_nums}")
# option_type_nums = sum(1 for key in options_info.keys() if key.startswith('option_type_'))
# logger.debug(f"총 옵션 타입 수: {option_type_nums}")
options_info = collect_option_data(driver)
logger.debug(f"수집된 옵션 정보: {options_info}")
option_type_nums = len(options_info)
time.sleep(30)
logger.debug(f"============================== 잠시 대기 =============================")
# 현재 전체 옵션갯수 가져오기
# 각 옵션 타입별로 XPath를 문자열 포맷을 사용하여 한 줄로 작성
option_num_xpaths = [
"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{}]/div/div/div[2]/div/div/div[4]/div/div/label/span[2]".format(idx)
for idx in range(1, 4) # 옵션 타입이 3개까지 있음
]
# option_num_xpaths = [
# "//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{}]/div/div/div[2]/div/div/div[4]/div/div/label/span[2]".format(idx)
# for idx in range(1, 4) # 옵션 타입이 3개까지 있음
# ]
# 각 옵션 타입의 갯수를 가져와서 options_info에 업데이트
for idx, option_num_xpath in enumerate(option_num_xpaths[:option_type_nums], start=1):
try:
option_num_element = return_element(driver, 'XPATH', option_num_xpath, 5)
if option_num_element:
option_number = int(re.search(r'\d+', option_num_element.text).group())
logger.debug(f"옵션타입 [{idx}] 의 갯수 : {option_number}")
options_info[f'option_type_{idx}']['options_count'] = option_number
else:
logger.debug(f"옵션타입 {idx} 요소를 찾을 수 없음.")
options_info[f'option_type_{idx}']['options_count'] = None
except Exception as e:
logger.error(f"옵션 타입 {idx} 갯수를 가져오는 중 오류 발생: {e}", exc_info=True)
# for idx, option_num_xpath in enumerate(option_num_xpaths[:option_type_nums], start=1):
# try:
# option_num_element = return_element(driver, 'XPATH', option_num_xpath, 5)
# if option_num_element:
# option_number = int(re.search(r'\d+', option_num_element.text).group())
# logger.debug(f"옵션타입 [{idx}] 의 갯수 : {option_number}")
# options_info[f'option_type_{idx}']['options_count'] = option_number
# else:
# logger.debug(f"옵션타입 {idx} 요소를 찾을 수 없음.")
# options_info[f'option_type_{idx}']['options_count'] = None
# except Exception as e:
# logger.error(f"옵션 타입 {idx} 갯수를 가져오는 중 오류 발생: {e}", exc_info=True)
# # 가격 낮은 순으로 정렬
# logger.debug("가격 낮은 순으로 정렬")
@ -150,13 +161,15 @@ def modify_option_page(driver, product_info, translator, login_info):
try:
logger.debug(f"옵션타입 {option_idx}에 대한 처리 시작")
logger.debug("가격 낮은 순으로 정렬")
low_price_order_xpath = f"//div[{option_idx}]/div/div/div[2]/div/div/div[4]/div[2]/div[2]/div/div[4]/button"
click_element(driver, 'XPATH', low_price_order_xpath, 10, 'js')
# low_price_order_xpath = f"//div[{option_idx}]/div/div/div[2]/div/div/div[4]/div[2]/div[2]/div/div[4]/button"
low_price_order_css = "div#productMainContentContainerId div:nth-child(2) > div > button[type=\"button\"]:nth-child(3)"
# click_element(driver, 'XPATH', low_price_order_xpath, 10, 'js')
click_element(driver, 'CSS_SELECTOR', low_price_order_css, 10, 'js')
if not simpleMode: # 심플모드일 경우 옵션 편집하지 않음. 옵션 번역만.
edit_option(driver, option_idx, options_info[f'option_type_{option_idx}']['options_count']) # 각 옵션의 전체 체크박스 해제
# 가격 낮은 순으로 재정렬
logger.debug("가격 낮은 순으로 재정렬")
click_element(driver, 'XPATH', low_price_order_xpath, 10, 'js')
# logger.debug("가격 낮은 순으로 재정렬")
# click_element(driver, 'XPATH', low_price_order_xpath, 10, 'js')
option_name_trans(driver, translator, product_info, option_idx, options_info[f'option_type_{option_idx}']['options_count'], allowed_special_chars, special_char_replacements)
except KeyError:
logger.error(f"옵션타입 {option_idx}에 대한 정보가 없습니다.")
@ -251,11 +264,13 @@ def option_name_trans(driver, translator, product_info, option_type_number, opti
logger.debug("선택된 옵션명 DeepL로 번역 후 새로운 옵션명 입력")
ori_optionNames = []
deepl_trans_optionNames = []
# 원본 옵션명 추출
# 원본 옵션명 추출 및 이미지 URL 확인
try:
for i in range(1, option_count + 1):
if option_type_number == 1:
ori_optionName_xpath = f"//div[{option_type_number}]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[{i}]/div/div[1]/div/div[3]/div[3]/span"
optionImage_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{option_type_number}]/div/div[2]/div/div[{i}]/div/div[2]/div/img"
deleteButton_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{option_type_number}]/div/div[2]/div/div[{i}]/div/div[2]/div/span"
elif option_type_number == 2:
ori_optionName_xpath = f"//div[{option_type_number}]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[{i}]/div/div[1]/div/div[2]/div[3]/span"
else: # option_type_number == 3
@ -266,10 +281,35 @@ def option_name_trans(driver, translator, product_info, option_type_number, opti
cleaned_ori_optionName = replace_or_remove_special_chars(ori_optionName, allowed_special_chars, special_char_replacements)
logger.debug(f"정제된 {i}번째 원본 옵션명 : {cleaned_ori_optionName}")
ori_optionNames.append(cleaned_ori_optionName)
# 1번 옵션타입의 이미지를 번역하고 업로드
if option_type_number == 1:
try:
option_image_element = return_element(driver, 'XPATH', optionImage_xpath, 3)
if option_image_element:
option_image_url = option_image_element.get_attribute('src')
logger.debug(f"옵션 이미지 URL : {option_image_url}")
translated_image = image_trans(option_image_url, translator, 'translate', logger)
if translated_image:
# 이미지 번역 후 업로드
temp_file_path = save_image_to_tempfile(translated_image)
# 이미지 삭제 버튼 클릭
click_element(driver, 'XPATH', deleteButton_xpath, 5, 'ac')
logger.debug(f"이미지 삭제 버튼 클릭 완료")
# 새로운 이미지 업로드
upload_image(driver)
else:
logger.debug(f"옵션 이미지 번역 실패: {option_image_url}")
else:
logger.debug(f"{i}번째 옵션에 이미지 없음")
except Exception as e:
logger.error(f"옵션 이미지 처리 중 오류 발생: {e}", exc_info=True)
except Exception as e:
logger.debug(f"원본옵션명 처리중 에러발생 : {e}", exc_info=True)
# 원본 옵션명을 하나의 텍스트로 합치기
# combined_ori_optionNames = '\n\n'.join(ori_optionNames)
@ -389,4 +429,336 @@ def update_price_range(driver, options_info, product_info):
logger.debug(f"전체 옵션의 가격 범위 업데이트: 최소값 {overall_min_price}, 최대값 {overall_max_price}")
except Exception as e:
logger.error(f"가격 범위 업데이트 중 오류 발생: {e}", exc_info=True)
logger.error(f"가격 범위 업데이트 중 오류 발생: {e}", exc_info=True)
def save_image_to_tempfile(image):
"""
이미지를 임시 파일로 저장합니다.
Args:
- image (PIL.Image): 번역된 이미지 객체
Returns:
- temp_file_path (str): 임시 파일 경로
"""
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".png")
image.save(temp_file, format="PNG")
temp_file_path = temp_file.name
temp_file.close()
logger.debug(f"임시 파일로 저장된 이미지 경로: {temp_file_path}")
return temp_file_path
def upload_image(driver, option_item_index, temp_file_path):
"""
번역된 이미지를 업로드합니다.
Args:
- driver: WebDriver 인스턴스
- option_item_index (int): 옵션 아이템의 인덱스 (1, 2, 3 )
- temp_file_path (str): 임시 파일 경로
"""
try:
# 기존 이미지 삭제 버튼 클릭
delete_button_css = f"div#productMainContentContainerId li:nth-child({option_item_index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > div.ant-row.ant-row-no-wrap.ant-row-space-between.ant-row-middle.css-1li46mu > div:nth-child(1) > div > span"
delete_button_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, delete_button_css))
)
delete_button_element.click()
logger.debug(f"{option_item_index}번째 옵션 아이템의 이미지 삭제 버튼 클릭 완료")
time.sleep(1) # 이미지 삭제 대기
# 이미지 업로드 버튼 클릭
upload_button_css = f"div#productMainContentContainerId li:nth-child({option_item_index}) > div > div:nth-child(1) > div > div:nth-child(2) > div > div > img"
upload_button_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, upload_button_css))
)
upload_button_element.click()
logger.debug(f"{option_item_index}번째 옵션 아이템의 이미지 업로드 버튼 클릭 완료")
# 이미지 업로드 다이얼로그의 파일 업로드 버튼 클릭
file_upload_dialog_css = "span > div > div > div:nth-child(2) > div"
file_upload_dialog_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, file_upload_dialog_css))
)
file_upload_dialog_element.click()
logger.debug("파일 업로드 버튼 클릭 완료")
# 파일 선택 대화상자에 임시 이미지 파일 경로를 입력하여 업로드
driver.find_element(By.CSS_SELECTOR, 'input[type="file"]').send_keys(temp_file_path)
logger.debug(f"임시 이미지 파일 경로 지정: {temp_file_path}")
# 이미지 삽입 버튼 클릭
insert_button_css = "div.ant-modal-footer > button[type=\"button\"].ant-btn.css-1li46mu.ant-btn-primary"
insert_button_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, insert_button_css))
)
insert_button_element.click()
logger.debug("이미지 삽입 버튼 클릭 완료")
# 임시 파일 삭제
os.remove(temp_file_path)
logger.debug(f"임시 파일 삭제 완료: {temp_file_path}")
except Exception as e:
logger.error(f"이미지 업로드 중 에러 발생: {e}", exc_info=True)
def collect_option_data(driver):
"""
웹페이지에서 옵션 타입의 갯수와 타입별 옵션 아이템의 갯수를 수집합니다.
Parameters:
- driver: WebDriver 인스턴스
Returns:
- filtered_options_info (dict): 옵션 타입과 타입별 옵션 아이템 갯수를 포함하는 필터링된 딕셔너리
"""
options_info = {}
try:
# 먼저 상품 유형을 확인합니다.
if not is_option_product(driver):
logger.debug("단일 상품이므로 옵션 정보 수집을 생략합니다.")
return options_info # 단일 상품일 경우 빈 딕셔너리를 반환
# 옵션 타입들의 부모 컨테이너 CSS
option_types_container_css = "div#productMainContentContainerId div.sc-bCrHVQ.fRmCVg > div:nth-child(2) > div > div > div:nth-child(2) > div > div"
# option_types_container_css = "div#productMainContentContainerId > div > div:nth-child(2) > div > div > div:nth-child(2)"
option_types_container = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, option_types_container_css))
)
# 옵션 타입 요소들을 찾기 위한 CSS
option_type_css = "div.ant-row.css-1li46mu > div > div"
# 옵션 타입 갯수 수집
option_type_elements = option_types_container.find_elements(By.CSS_SELECTOR, option_type_css)
option_type_count = len(option_type_elements)
logger.debug(f"옵션 타입의 총 갯수 기존 : {option_type_count}")
# 옵션 타입 컨테이너의 CSS 선택자
option_type_css = "div#productMainContentContainerId div.sc-bCrHVQ.fRmCVg > div:nth-child(2) > div > div > div:nth-child(2) > div"
# 각 옵션 타입별로 `div.sc-stxIr.eeUZbv` 요소의 갯수를 확인
option_type_elements_by_css = driver.find_elements(By.CSS_SELECTOR, option_type_css)
option_type_count_by_css = len(option_type_elements_by_css)
logger.debug(f"옵션 타입의 총 갯수: {option_type_count_by_css}")
for idx in range(1, option_type_count + 1):
# 옵션 타입 이름 추출
# option_type_name_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{idx}]/div/div/div[2]/div/div/div[2]/div/span/input"
# option_type_name_element = WebDriverWait(driver, 10).until(
# EC.presence_of_element_located((By.XPATH, option_type_name_xpath))
# )
# option_type_name = option_type_name_element.get_attribute('value').strip()
option_type_name_css = f"div#productMainContentContainerId div:nth-child({idx}) > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.ant-row.ant-row-no-wrap.ant-row-middle.css-1li46mu > div:nth-child(1) > span > input"
option_type_name__by_css_element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, option_type_name_css))
)
option_type_name = option_type_name__by_css_element.get_attribute('value').strip()
# 옵션 타입별 옵션 아이템 갯수 추출
# option_items_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{idx}]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li"
# option_items = driver.find_elements(By.CSS_SELECTOR, option_items_xpath)
# option_items_count = len(option_items)
option_items_css = f"div#productMainContentContainerId div:nth-child({idx}) > div > div > div.ant-collapse-content.ant-collapse-content-active > div > div > div.sc-kjNGdX.cQdCox > div.ant-list.ant-list-split.css-1li46mu > div > div > ul > li"
option_items = driver.find_elements(By.CSS_SELECTOR, option_items_css)
option_items_count = len(option_items)
# 각 옵션 타입별 옵션명, 이미지 및 가격을 수집
option_names_and_images = collect_option_names_and_images_and_price(driver, idx, option_items_count)
options_info[f'option_type_{idx}'] = {
'name': option_type_name,
'items_count': option_items_count,
'items': option_names_and_images
}
logger.debug(f"옵션 타입 {idx}: {option_type_name}, 옵션 아이템 수: {option_items_count}")
for item in option_names_and_images:
logger.debug(f" - 옵션 아이템: 이름={item['name']}, 이미지 URL={item['image_url']}, 가격={item['low_price']} - {item['high_price']}")
except Exception as e:
logger.error(f"옵션 타입 및 아이템 수집 중 오류 발생: {e}", exc_info=True)
return options_info
def collect_option_names_and_images_and_price(driver, option_type_number, option_items_count):
"""
옵션 타입별로 원본 옵션명, 옵션 이미지, 옵션 가격을 수집합니다.
Parameters:
- driver: WebDriver 인스턴스
- option_type_number: 옵션 타입 번호 (1, 2, 3 )
- option_items_count: 해당 옵션 타입의 옵션 아이템 갯수
Returns:
- option_data (list): 옵션명, 이미지 URL, 가격을 포함하는 리스트
"""
option_data = []
try:
for i in range(1, option_items_count + 1):
# 원본 옵션명 수집
option_name_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{option_type_number}]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[{i}]/div/div[1]/div/div[3]/div[3]/span"
option_name_element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, option_name_xpath))
)
option_name = option_name_element.text.strip()
# 옵션 이미지 URL 수집 (옵션 타입 1에만 옵션이미지 존재)
option_image_url = None
if option_type_number == 1:
option_image_xpath = f"div#productMainContentContainerId li:nth-child({i}) > div > div:nth-child(1) > div > div:nth-child(2) > div > img"
try:
option_image_element = driver.find_element(By.CSS_SELECTOR, option_image_xpath)
option_image_url = option_image_element.get_attribute('src')
except Exception:
logger.debug(f"{i}번째 옵션에 이미지 없음")
# 옵션 가격 수집
option_price_xpath = f"div#productMainContentContainerId li:nth-child({i}) > div > div:nth-child(1) > div > div:nth-child(3) > div:nth-child(1) > div:nth-child(2) > span > sup"
try:
option_price_element = driver.find_element(By.CSS_SELECTOR, option_price_xpath)
option_price_text = option_price_element.get_attribute('title') # 또는 .text를 사용할 수도 있음
# 가격 문자열에서 숫자만 추출 (천 단위 구분자를 포함하는 경우 처리)
price_range = re.findall(r'\d+', option_price_text.replace(',', ''))
low_price, high_price = map(int, price_range) if len(price_range) == 2 else (int(price_range[0]), int(price_range[0]))
except Exception:
logger.debug(f"{i}번째 옵션에 가격 없음")
low_price = high_price = None
option_data.append({
'name': option_name,
'image_url': option_image_url,
'low_price': low_price,
'high_price': high_price
})
logger.debug(f"옵션 {i}: 이름={option_name}, 이미지 URL={option_image_url}, 가격={low_price} - {high_price}")
except Exception as e:
logger.error(f"옵션명, 이미지 및 가격 수집 중 오류 발생: {e}", exc_info=True)
return option_data
def is_option_product(driver):
"""
웹페이지에서 현재 상품이 '단일 상품'인지 '옵션 상품'인지 확인합니다.
Parameters:
- driver: WebDriver 인스턴스
Returns:
- bool: 옵션 상품이면 True, 단일 상품이면 False
"""
try:
# '옵션 상품등록' 또는 '단일 상품등록' 선택 여부 확인
radio_group_css = "div#productMainContentContainerId div.ant-row.css-1li46mu > div"
radio_group_element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, radio_group_css))
)
# 라디오 버튼의 선택 상태 확인
option_radio_xpath = "//label[span[text()='옵션 상품등록']]//input[@type='radio' and @value='false']"
single_radio_xpath = "//label[span[text()='단일 상품등록']]//input[@type='radio' and @value='true']"
option_radio_checked = radio_group_element.find_element(By.XPATH, option_radio_xpath).is_selected()
single_radio_checked = radio_group_element.find_element(By.XPATH, single_radio_xpath).is_selected()
if option_radio_checked and not single_radio_checked:
logger.debug("상품 유형: 옵션 상품등록")
return True
else:
logger.debug("상품 유형: 단일 상품등록")
return False
except Exception as e:
logger.error(f"상품 유형 확인 중 오류 발생: {e}", exc_info=True)
logger.debug("상품 유형 오류 발생으로 기본설정인 단일 상품등록으로 진행합니다.")
return False # 오류 발생 시 기본적으로 단일 상품으로 처리
def filter_and_select_options(driver, option_type_number, option_data):
"""
미끼 옵션을 제거하고 유효한 옵션을 선택합니다.
Parameters:
- driver: WebDriver 인스턴스
- option_type_number: 옵션 타입 번호 (1, 2, 3 )
- option_data (list): 옵션명, 이미지 URL, 가격을 포함하는 리스트
"""
try:
# 가격 데이터만 추출하여 정렬
prices = sorted([item['low_price'] for item in option_data if item['low_price'] is not None])
if not prices:
logger.error("가격 데이터가 없습니다.")
return
# 미끼 옵션을 식별하여 제거
valid_items = []
for i, base_price in enumerate(prices):
range_limit = base_price * 1.5
within_range = [price for price in prices if price <= range_limit]
if len(within_range) == len(prices):
valid_items = [item for item in option_data if item['low_price'] in within_range]
break
if not valid_items:
valid_items = option_data
# 전체 체크박스 해제
select_all_checkbox_xpath = f"//div[{option_type_number}]/div/div/div[2]/div/div/div[4]/div[2]/div[1]/label/span[1]"
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, select_all_checkbox_xpath))
).click()
time.sleep(1)
# 필터링된 옵션을 낮은 가격순으로 정렬
valid_items = sorted(valid_items, key=lambda x: x['low_price'])
# 최대 10개 옵션만 선택, 옵션이 5개 이하라면 모든 옵션 선택
for i, item in enumerate(valid_items):
if i >= 10:
break
option_checkbox_xpath = f"//div[{option_type_number}]/div/div/div[2]/div/div/div[5]/div[1]/div/div/ul/li[{i + 1}]/div/div[1]/div/div[1]/label/span[1]"
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, option_checkbox_xpath))
).click()
time.sleep(0.5)
logger.debug(f"옵션 타입 {option_type_number}의 유효한 옵션 아이템 선택 완료")
except Exception as e:
logger.error(f"옵션 선택 중 오류 발생: {e}", exc_info=True)
def click_sort_by_price(driver, option_type_number):
"""
옵션 타입별로 가격 내림차순 정렬 버튼을 클릭합니다.
Parameters:
- driver: WebDriver 인스턴스
- option_type_number: 옵션 타입 번호 (1, 2, 3 )
"""
try:
sort_button_xpath = f"//div[@id='productMainContentContainerId']/div/div[2]/div/div/div[2]/div/div[{option_type_number}]/div/div/div[2]/div/div/div[4]/div[2]/div[2]/div/div[4]/button"
sort_button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, sort_button_xpath))
)
sort_button.click()
logger.debug(f"옵션 타입 {option_type_number}의 가격 내림차순 정렬 버튼 클릭 완료")
time.sleep(1) # 정렬이 완료될 시간을 줍니다.
# low_price_order_css = "div#productMainContentContainerId div:nth-child(2) > div > button[type=\"button\"]:nth-child(3)"
# # click_element(driver, 'XPATH', low_price_order_xpath, 10, 'js')
# click_element(driver, 'CSS_SELECTOR', low_price_order_css, 10, 'js')
except Exception as e:
logger.error(f"가격 내림차순 정렬 버튼 클릭 중 오류 발생: {e}", exc_info=True)

View File

@ -112,8 +112,8 @@ def modify_products(driver, gemini, translator, mongo_config, login_info, set_nu
# product_info = set_product_info() # 상품정보리스트 생성
autoPercentyProductsDB = AutoPercentyProductsDB(mongo_config)
autoPercentyProductsDB.reset_product_by_id('660d636271e50111cf71284e')
autoPercentyProductsDB.reset_product_by_id('660d635371e50111cf712842')
# autoPercentyProductsDB.reset_product_by_id('660d636271e50111cf71284e')
# autoPercentyProductsDB.reset_product_by_id('660d635371e50111cf712842')
try:
if login_info['per_mode']: