1
0
Fork 0

XPAHT 수정

This commit is contained in:
K.H.CHOI 2024-03-30 16:24:46 +09:00
parent 63842a190a
commit 9ffe5d8f95
7 changed files with 200 additions and 147 deletions

View File

@ -4,6 +4,7 @@ from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import logging
import time
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
@ -23,23 +24,27 @@ def click_element(driver, element_type, element_identifier, wait_time=10, click_
try:
element = WebDriverWait(driver, wait_time).until(
EC.visibility_of_element_located((getattr(By, element_type), element_identifier))
# EC.presence_of_element_located((getattr(By, element_type), element_identifier))
)
if click_type == 'normal':
element.click()
elif click_type == 'js':
# driver.execute_script("arguments[0].scrollIntoView();", element)
driver.execute_script("arguments[0].scrollIntoView();", element)
time.sleep(0.2)
driver.execute_script("arguments[0].click();", element)
elif click_type == 'ac':
actions = ActionChains(driver)
actions.move_to_element(element).perform() # 요소로 스크롤
logger.debug(f"'{element}' 요소로 스크롤 실행")
time.sleep(0.2)
ActionChains(driver).click(element).perform()
logger.debug(f"'{element_identifier}' 요소를 성공적으로 클릭함.")
except TimeoutException:
logger.debug(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함.")
logger.error(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함.")
except Exception as e:
logger.debug(f"예상치 못한 오류 발생: {e}")
logger.error(f"예상치 못한 오류 발생: {e}")
def return_element(driver, element_type, element_identifier, wait_time=10):
"""
@ -54,15 +59,31 @@ def return_element(driver, element_type, element_identifier, wait_time=10):
- presence_of_element_located : 페이지 로딩이 완료되었는지 확인하거나, 특정 요소가 DOM에 추가되었는지를 확인할
"""
try:
element = WebDriverWait(driver, wait_time).until(
# 요소가 DOM에 존재하는지 확인
element_present = EC.presence_of_element_located((getattr(By, element_type), element_identifier))
element = WebDriverWait(driver, wait_time).until(element_present)
# 요소가 사용자 화면에 보이도록 스크롤
driver.execute_script("arguments[0].scrollIntoView(true);", element)
# 요소가 실제로 사용자에게 보이는지 다시 확인
element_visible = WebDriverWait(driver, wait_time).until(
EC.visibility_of_element_located((getattr(By, element_type), element_identifier))
)
logger.debug(f"'{element}' 요소를 성공적으로 찾음.")
return element
except TimeoutException:
logger.debug(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함.")
return None
logger.debug(f"'{element_visible}' 요소를 성공적으로 찾음.")
return element_visible
except TimeoutException as e:
logger.debug(f"'{element_identifier}' 요소를 {wait_time} 초 이내에 찾지 못함. 예외: {e}")
# 시각적으로 보이지 않는 경우, DOM 내 존재 여부만 확인
try:
element_in_dom = driver.find_element(getattr(By, element_type), element_identifier)
logger.debug(f"'{element_identifier}' 요소는 DOM 내에 존재하지만 보이지 않음.")
return element_in_dom
except Exception as e:
logger.debug(f"DOM 내에서도 '{element_identifier}' 요소를 찾을 수 없음. 예외: {e}")
return None
except Exception as e:
logger.debug(f"예상치 못한 오류 발생: {e}")

View File

@ -383,13 +383,17 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
product_high_cost = product_info.tao_high_price
image_src = product_info.main_image_url
# cat = click_element(driver, 'XPATH', '//div[8]/div/div/div[2]/div/div/div/span[2]/div/div', 10, 'js')
cat = return_element(driver, 'XPATH', '//div[8]/div/div/div[2]/div/div/div/span[2]/div/div', 10)
logger.debug(f"퍼센티 등록 화면에 표시된 카테고리 텍스트 : {cat.text}")
product_info.per_cat_code = cat.text
naver_code = find_naver_code(cat.text, json_naver_codes)
logger.debug(f"검색된 스스 캣코드 : {naver_code}")
product_info.naver_code = naver_code
try:
# cat = click_element(driver, 'XPATH', '//div[8]/div/div/div[2]/div/div/div/span[2]/div/div', 10, 'js')
cat = return_element(driver, 'XPATH', '//div[8]/div/div/div[2]/div/div/div/span[2]/div/div', 10)
logger.debug(f"퍼센티 등록 화면에 표시된 카테고리 텍스트 : {cat.text}")
product_info.per_cat_code = cat.text
naver_code = find_naver_code(cat.text, json_naver_codes)
logger.debug(f"검색된 스스 캣코드 : {naver_code}")
product_info.naver_code = naver_code
except Exception as e:
logger.debug(f"카테고리 코드 검색 중 예외 발생 : {e}")
naver_code = ""
# click_element('XPATH', '/html/body/div[7]/div/div[3]/div/div[2]/div[1]/div/div[2]/div[8]/div/div/div[2]/div[1]/div/div/span[2]/div/div')
@ -399,9 +403,11 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
# 상세페이지 탭으로 이동
# detail_tab = driver.find_element(By.ID, "rc-tabs-0-tab-5")
try:
detail_tab_xpath = ".ant-tabs-tab:nth-child(6)"
detail_tab = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".ant-tabs-tab:nth-child(6)"))
)
save_button_xpath = "//button[contains(.,'저장하기')]"
save_button = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//button[contains(.,'저장하기')]"))
)
@ -463,13 +469,15 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
logger.debug("네이버쇼핑 파싱 완료")
try:
html_btn = WebDriverWait(driver, 10).until(
# EC.presence_of_element_located((By.CSS_SELECTOR, ".ck-source-editing-button"))
EC.presence_of_element_located((By.CLASS_NAME, "ck.ck-button.ck-source-editing-button.ck-off.ck-button_with-text"))
# EC.presence_of_element_located((By.CSS_SELECTOR, "button.ck.ck-button.ck-source-editing-button.ck-off.ck-button_with-text"))
)
logger.debug("HTML 수정 버튼을 성공적으로 찾았습니다.")
html_btn.click()
html_btn_xpath = "ck.ck-button.ck-source-editing-button.ck-off.ck-button_with-text"
click_element(driver, 'XPATH', html_btn_xpath, 10, 'js')
# html_btn = WebDriverWait(driver, 10).until(
# # EC.presence_of_element_located((By.CSS_SELECTOR, ".ck-source-editing-button"))
# EC.presence_of_element_located(By.CLASS_NAME, html_btn_xpath)
# # EC.presence_of_element_located((By.CSS_SELECTOR, "button.ck.ck-button.ck-source-editing-button.ck-off.ck-button_with-text"))
# )
# logger.debug("HTML 수정 버튼을 성공적으로 찾았습니다.")
# html_btn.click()
logger.debug("HTML 수정 버튼 클릭 .")
except Exception as e:
logger.debug(f"HTML 수정 버튼 요소를 찾을 수 없습니다. : {e}")
@ -503,7 +511,7 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
# 원본 URL을 빈문자열로 대체
logger.debug("원본 URL을 빈 문자열로번역된 이미지로 대체")
logger.debug("원본 URL을 빈 문자열로 대체")
for original_url in detail_images:
current_value = current_value.replace(original_url, "")
@ -540,12 +548,13 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
driver.execute_script("arguments[0].setAttribute('data-value', arguments[1]);", textarea, new_value)
# driver.execute_script("arguments[0].innerHTML = arguments[1]", textarea, new_value)
time.sleep(0.2)
time.sleep(1)
# driver.execute_script("arguments[0].innerHTML = arguments[1]", detail_content, new_value);
logger.debug("새로운 data-value 값으로 설정되었습니다.")
save_button.click()
# save_button.click()
click_element(driver, 'XPATH', save_button_xpath, 5, 'js')
time.sleep(0.2)
@ -555,7 +564,9 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
# textarea.send_keys(Keys.ENTER)
# logger.debug("엔터키 전송.")
html_btn.click()
# html_btn.click()
click_element(driver, 'XPATH', html_btn_xpath, 5, 'js')
logger.debug("HTML 수정 버튼 다시 클릭하여 기본편집페이지로 돌아감.")
time.sleep(0.2)
@ -579,22 +590,23 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
logger.debug("상세페이지 이미지 번역 시작")
for i, detail_image in enumerate(detail_images):
logger.debug(f"상세페이지 {i}번째 이미지 번역 시작")
logger.debug(f"이미지 타입 : {type(detail_image)}")
returned_img = image_trans(detail_image, 'translate')
image_to_clipboard(returned_img)
logger.debug("번역 완료 및 부텨넣기")
detail_content.send_keys(Keys.CONTROL, 'v')
detail_content.send_keys(Keys.ENTER)
try:
for i, detail_image in enumerate(detail_images):
logger.debug(f"상세페이지 {i+1}번째 이미지 번역 시작")
logger.debug(f"이미지 타입 : {type(detail_image)}")
returned_img = image_trans(detail_image, 'translate')
image_to_clipboard(returned_img)
logger.debug("번역 완료 및 부텨넣기")
detail_content.send_keys(Keys.CONTROL, 'v')
detail_content.send_keys(Keys.ENTER)
logger.debug(f"{i}번째 이미지 붙여넣기 완료")
# translated_image_urls.append(returned_img_path)
logger.debug("이미지 번역 완료")
logger.debug(f"{i}번째 이미지 붙여넣기 완료")
# translated_image_urls.append(returned_img_path)
logger.debug("이미지 번역 완료")
except Exception as e:
logger.error(f"이미지 번역 중 에러발생 : {e}")
logger.debug("====번역이미지 붙여넣기 완료=====")
@ -662,15 +674,16 @@ def modify_detail_page(driver, gemini, product_info, delv_collection, json_naver
time.sleep(2)
# 저장 버튼 클릭
try:
save_button = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//button[contains(.,'저장하기')]"))
)
logger.debug("저장 버튼을 성공적으로 찾았습니다.")
except Exception as e:
logger.debug(f"저장 버튼 요소를 찾을 수 없습니다. : {e}")
# try:
# save_button = WebDriverWait(driver, 10).until(
# EC.presence_of_element_located((By.XPATH, "//button[contains(.,'저장하기')]"))
# )
# logger.debug("저장 버튼을 성공적으로 찾았습니다.")
# except Exception as e:
# logger.debug(f"저장 버튼 요소를 찾을 수 없습니다. : {e}")
# save_button = driver.find_element(By.XPATH, "//button[contains(.,'저장하기')]")
save_button.click()
# save_button.click()
click_element(driver, "XPATH", save_button_xpath, 5, 'js')
time.sleep(0.5)

View File

@ -30,30 +30,33 @@ def find_naver_code_ori(base_category):
def find_naver_code(base_category, json_naver_codes):
logger.debug("네이버 카테고리 코드 찾기")
logger.debug(f"주어진 카테고리 : {base_category}")
category_parts = re.split(r'>|-', base_category)
logger.debug(f"카테고리 분리 : {category_parts}")
try:
category_parts = re.split(r'>|-', base_category)
logger.debug(f"카테고리 분리 : {category_parts}")
base_category1Name, base_category2Name, base_category3Name, base_category4Name = (category_parts + [None]*4)[:4]
base_category1Name, base_category2Name, base_category3Name, base_category4Name = (category_parts + [None]*4)[:4]
for item in json_naver_codes:
try:
# category3Name과 category4Name가 없거나 NaN인 경우를 처리합니다.
category3Name_item = item.get('category3Name')
if isinstance(category3Name_item, dict) and '$numberDouble' in category3Name_item:
category3Name_item = None # NaN 값 처리
for item in json_naver_codes:
try:
# category3Name과 category4Name가 없거나 NaN인 경우를 처리합니다.
category3Name_item = item.get('category3Name')
if isinstance(category3Name_item, dict) and '$numberDouble' in category3Name_item:
category3Name_item = None # NaN 값 처리
category4Name_item = item.get('category4Name')
if isinstance(category4Name_item, dict) and '$numberDouble' in category4Name_item:
category4Name_item = None # NaN 값 처리
category4Name_item = item.get('category4Name')
if isinstance(category4Name_item, dict) and '$numberDouble' in category4Name_item:
category4Name_item = None # NaN 값 처리
# 조건에 따라 검색합니다.
if (item.get('category1Name') == base_category1Name and
item.get('category2Name') == base_category2Name and
(category3Name_item == base_category3Name or base_category3Name is None) and
(category4Name_item == base_category4Name or base_category4Name is None)):
logger.debug(f"찾은 카테고리 코드 : {item['Naver_code']}")
return item['Naver_code'] # 조건에 맞는 첫 번째 코드를 반환하고 함수 종료
except Exception as e:
logger.error(f"Error processing item: {e}")
continue
return None # 조건에 맞는 코드를 찾지 못한 경우
# 조건에 따라 검색합니다.
if (item.get('category1Name') == base_category1Name and
item.get('category2Name') == base_category2Name and
(category3Name_item == base_category3Name or base_category3Name is None) and
(category4Name_item == base_category4Name or base_category4Name is None)):
logger.debug(f"찾은 카테고리 코드 : {item['Naver_code']}")
return item['Naver_code'] # 조건에 맞는 첫 번째 코드를 반환하고 함수 종료
except Exception as e:
logger.error(f"Error processing item: {e}")
continue
return None # 조건에 맞는 코드를 찾지 못한 경우
except Exception as e:
logger.error(f"find_naver_code 함수 실행 중 에러 발생 : {e}")

View File

@ -23,6 +23,8 @@ def modify_option_page(driver, product_info):
"" : ")",
"[" : "(",
"]" : ")",
"," : ".",
}
# 옵션 정보를 담을 딕셔너리 초기화
options_info = {}
@ -172,7 +174,7 @@ def modify_option_page(driver, product_info):
update_price_range(driver, options_info, product_info)
save_xpath="//button[contains(.,'저장하기')]"
click_element(driver, 'XPATH', save_xpath, 10)
click_element(driver, 'XPATH', save_xpath, 10, 'js')
logger.debug("옵션 정리 후 저장버튼 클릭 완료")
def edit_option(driver, option_type, option_count):

View File

@ -20,69 +20,83 @@ logger = logging.getLogger('default_logger')
def image_trans(image_url, convert_type):
# 이미지를 URL로부터 읽어옵니다.
image = read_image_from_url(image_url)
logger.debug(f"이미지 타입 : {type(image)}")
# 이미지에서 텍스트 인식
detected_texts = detect_text(image)
if not detected_texts:
logger.debug("텍스트가 없는 이미지")
pil_img = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
return pil_img
logger.debug("Detected texts:", detected_texts)
if image is None:
return None # 이미지 로드에 실패한 경우, 추가 처리를 중단하고 None을 반환
try:
logger.debug(f"이미지 타입 : {type(image)}")
# 처리된 이미지 경로 설정
img_name = "output"
thumb_image_path = f'img/{img_name}_thumbnail.jpg'
translated_image_path = f'img/{img_name}_translated.jpg'
# 이미지에서 텍스트 인식
detected_texts = detect_text(image)
if not detected_texts:
logger.debug("텍스트가 없는 이미지")
pil_img = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
return pil_img
logger.debug("Detected texts:", detected_texts)
# 처리된 이미지 경로 설정
Thumb_image_path = f'img/{img_name}_Thumb.jpg'
processed_image_path = f'img/{img_name}_processed.jpg'
translated_image_path = f'img/{img_name}_translated.jpg'
inpainted_image_path = f'img/{img_name}_inpainted.jpg'
# 처리된 이미지 경로 설정
img_name = "output"
thumb_image_path = f'img/{img_name}_thumbnail.jpg'
translated_image_path = f'img/{img_name}_translated.jpg'
if convert_type == 'thumbnail':
# 썸네일 생성 로직
logger.debug("썸네일 생성 처리 시작")
# 크롭과 인페인팅 결정 및 처리 함수 호출
removal_img = process_image_based_on_text_area(image, detected_texts, processed_image_path, threshold = 0.1)
# 추가 처리: 이미지 회전 및 좌우 반전
removal_img = flip_and_rotate_image(removal_img)
cv2.imwrite(Thumb_image_path, removal_img)
logger.debug(f"썸네일 이미지 생성완료: {Thumb_image_path}")
# 처리된 이미지 경로 설정
Thumb_image_path = f'img/{img_name}_Thumb.jpg'
processed_image_path = f'img/{img_name}_processed.jpg'
translated_image_path = f'img/{img_name}_translated.jpg'
inpainted_image_path = f'img/{img_name}_inpainted.jpg'
# 저장된 이미지 파일의 경로를 반환합니다.
return Thumb_image_path
if convert_type == 'thumbnail':
# 썸네일 생성 로직
logger.debug("썸네일 생성 처리 시작")
# 크롭과 인페인팅 결정 및 처리 함수 호출
removal_img = process_image_based_on_text_area(image, detected_texts, processed_image_path, threshold = 0.1)
# 추가 처리: 이미지 회전 및 좌우 반전
removal_img = flip_and_rotate_image(removal_img)
cv2.imwrite(Thumb_image_path, removal_img)
logger.debug(f"썸네일 이미지 생성완료: {Thumb_image_path}")
elif convert_type == 'translate':
# 2단계: 인페이팅 기법으로 텍스트 제거
inpainted_image = inpaint_text(image, detected_texts)
# cv2.imwrite(inpainted_image_path, inpainted_image)
# 이미지 번역 처리
logger.debug("이미지 번역 처리 시작")
# 번역된 텍스트 추출 및 삽입
texts_to_translate = [text for _, text, _, _, _ in detected_texts]
logger.debug(f"원본 텍스트: {texts_to_translate}")
translated_texts = translate_texts_translatepy(texts_to_translate)
logger.debug(f"번역 텍스트: {texts_to_translate}")
# translated_image = insert_text(inpainted_image_path, translated_texts, detected_texts)
translated_image = insert_text(inpainted_image, translated_texts, detected_texts)
# cv2.imwrite(translated_image_path, translated_image)
logger.debug(f"번역된 이미지 생성완료 : {translated_image_path}")
# 저장된 이미지 파일의 경로를 반환합니다.
return Thumb_image_path
# 번역된 이미지 변환합니다.
pil_img = Image.fromarray(cv2.cvtColor(translated_image, cv2.COLOR_BGR2RGB))
# buffered = BytesIO()
# pil_img.save(buffered, format="JPEG")
elif convert_type == 'translate':
# 2단계: 인페이팅 기법으로 텍스트 제거
inpainted_image = inpaint_text(image, detected_texts)
# cv2.imwrite(inpainted_image_path, inpainted_image)
# 이미지 번역 처리
logger.debug("이미지 번역 처리 시작")
# 번역된 텍스트 추출 및 삽입
texts_to_translate = [text for _, text, _, _, _ in detected_texts]
logger.debug(f"원본 텍스트: {texts_to_translate}")
translated_texts = translate_texts_translatepy(texts_to_translate)
logger.debug(f"번역 텍스트: {texts_to_translate}")
# translated_image = insert_text(inpainted_image_path, translated_texts, detected_texts)
translated_image = insert_text(inpainted_image, translated_texts, detected_texts)
# cv2.imwrite(translated_image_path, translated_image)
logger.debug(f"번역된 이미지 생성완료 : {translated_image_path}")
# 번역된 이미지 변환합니다.
pil_img = Image.fromarray(cv2.cvtColor(translated_image, cv2.COLOR_BGR2RGB))
# buffered = BytesIO()
# pil_img.save(buffered, format="JPEG")
return pil_img
except Exception as e:
logger.error(f"img_trans 이미지 변역 중 에러발생 : {e}")
return pil_img
# URL로부터 이미지를 읽어오는 함수
def read_image_from_url(image_url):
resp = urllib.request.urlopen(image_url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
if not image_url: # URL이 비어있는지 확인
logger.error("빈 URL이 제공되었습니다.")
return None
try:
resp = urllib.request.urlopen(image_url)
image = np.asarray(bytearray(resp.read()), dtype="uint8")
image = cv2.imdecode(image, cv2.IMREAD_COLOR)
return image
except Exception as e:
logger.error(f"이미지 로딩 중 오류 발생: {e}")
return None
# 외부에서 함수를 사용하는 예
# 이미지 URL과 원하는 변환 유형('thumbnail' 또는 'translate')을 인자로 넘깁니다.

View File

@ -21,11 +21,11 @@ def login(driver, login_info):
per_mode = login_info["per_mode"]
logger.debug("웹사이트에 접속 중...")
logger.info("웹사이트에 접속 중...")
driver.get("https://www.percenty.co.kr")
# time.sleep(1)
logger.debug("로그인 버튼 클릭...")
logger.info("로그인 버튼 클릭...")
# login_button = driver.find_element(By.CSS_SELECTOR, ".signList > .ant-btn-default > span")
# login_button.click()
@ -36,7 +36,7 @@ def login(driver, login_info):
)
login_button.click()
except TimeoutException:
logger.debug("로그인 버튼을 찾는데 실패했습니다.")
logger.error("로그인 버튼을 찾는데 실패했습니다.")
# try:
# login_button = WebDriverWait(driver, 30).until(
@ -49,7 +49,7 @@ def login(driver, login_info):
time.sleep(1)
logger.debug("이메일 주소 입력...")
logger.info("이메일 주소 입력...")
try:
email_input = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, ".ant-input:nth-child(4)"))
@ -57,45 +57,45 @@ def login(driver, login_info):
email_input.send_keys(per_email)
except:
logger.debug("이메일 주소 찾는 중 오류 발생: 요소를 찾을 수 없습니다.")
logger.error("이메일 주소 찾는 중 오류 발생: 요소를 찾을 수 없습니다.")
# email_input = driver.find_element(By.CSS_SELECTOR, ".ant-input:nth-child(4)")
time.sleep(0.1)
if per_mode:
logger.debug("사용자 패스워드 입력...")
logger.info("사용자 패스워드 입력...")
password_input = driver.find_element(By.CSS_SELECTOR, ".ant-input:nth-child(1)")
password_input.send_keys(per_password)
time.sleep(0.1)
else:
logger.debug("스위치 버튼 클릭...")
logger.info("스위치 버튼 클릭...")
switch_button = driver.find_element(By.CSS_SELECTOR, ".ant-switch-handle")
switch_button.click()
time.sleep(0.1)
logger.debug("직원 아이디 입력...")
logger.info("직원 아이디 입력...")
employee_id_input = driver.find_element(By.CSS_SELECTOR, ".ant-input:nth-child(2)")
employee_id_input.send_keys(per_em_email)
time.sleep(0.1)
logger.debug("직원 패스워드 입력...")
logger.info("직원 패스워드 입력...")
password_input = driver.find_element(By.CSS_SELECTOR, ".ant-input:nth-child(1)")
password_input.send_keys(per_em_password)
time.sleep(0.1)
logger.debug("로그인 버튼 클릭...")
logger.info("로그인 버튼 클릭...")
login_button = driver.find_element(By.CSS_SELECTOR, ".ant-btn-primary")
login_button.click()
time.sleep(2)
# 신규 상품 등록 페이지로이동
logger.debug("신규상품등록 버튼 클릭...")
logger.info("신규상품등록 버튼 클릭...")
try:
new_product_button = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//span[contains(.,'신규 상품 등록')]"))
)
except:
logger.debug("신규상품등록 버튼 찾는 중 오류 발생: 요소를 찾을 수 없습니다.")
logger.error("신규상품등록 버튼 찾는 중 오류 발생: 요소를 찾을 수 없습니다.")
# new_product_button = driver.find_element(By.XPATH, "//span[contains(.,'신규 상품 등록')]")
new_product_button.click()
time.sleep(2)

Binary file not shown.