forked from ckh08045/AutoPercenty
474 lines
25 KiB
Python
474 lines
25 KiB
Python
from selenium.webdriver.common.by import By
|
|
from selenium.webdriver.support.ui import WebDriverWait
|
|
from selenium.webdriver.common.action_chains import ActionChains
|
|
from selenium.webdriver.common.keys import Keys
|
|
from selenium.webdriver.support import expected_conditions as EC
|
|
from selenium.common.exceptions import TimeoutException
|
|
import time, re, math
|
|
import json
|
|
# from utils import log
|
|
from database_with_mongo import AutoPercentyProductsDB
|
|
from edit.detail1 import modify_detail_page
|
|
from edit.tag import edit_tag
|
|
from edit.options import modify_option_page
|
|
from edit.price import modify_price_page
|
|
from edit.title import modify_product_title
|
|
from edit.thumbnail import modify_thumb_page
|
|
from edit.trans_image import *
|
|
from edit.uploadMarket import *
|
|
from edit.action_elements import click_element, return_element, wait_element
|
|
import logging
|
|
|
|
from edit.product_info import ProductInfo
|
|
|
|
# 로거 인스턴스 가져오기
|
|
logger = logging.getLogger('default_logger')
|
|
|
|
# def set_product_info():
|
|
# '''
|
|
# 상품 정보 product_info 딕셔너리 초기화
|
|
|
|
# '''
|
|
# product_info = {
|
|
# 'id': None, #상품 아이디
|
|
# 'keyword_title': None, # 키워드 상품명
|
|
# 'product_title': None, # 수정 상품명
|
|
# 'trans_title': None, # 번역 상품명
|
|
# 'tao_high_price': None, # 타오바오의 최고 가격
|
|
# 'tao_low_price': None, # 타오바오의 최저 가격
|
|
# 'option_high_price': None, # 선택된 옵션 최고 가격
|
|
# 'option_low_price': None, # 선택된 옵션 최저 가격
|
|
# 'main_image_url': None, # 상품 메인썸네일 이미지 URL 리스트
|
|
# 'image_urls': [], # 상품 옵션 이미지 URL 리스트
|
|
# 'detail_image_urls': [], # 상품 상세페이지 이미지 URL 리스트
|
|
# 'thumb_image_urls': [], # 상품 썸네일 이미지 URL 리스트
|
|
# 'naver_code': None, # 네이버 카테고리 코드
|
|
# 'naver_avg_price': None, # 네이버 평균가격
|
|
# 'weight': None, # 상품 무게
|
|
# 'w_delv_fee': None, # 상품 무게배송비
|
|
# 'plus_fee': None, # 더하기마진
|
|
# 'return_fee': None, # 반품비
|
|
# 'init_delv_fee': None, # 초기반품비
|
|
# 'exchange_fee': None, # 교환배송비
|
|
# }
|
|
|
|
# return product_info
|
|
|
|
|
|
# 함수 이름과 해당하는 작업 함수 매핑
|
|
# function_mapping = {
|
|
# 'tag_modification': edit_tag,
|
|
# 'option_modification': modify_option_page,
|
|
# 'detail_page_modification': modify_detail_page,
|
|
# 'thumbnail_modification': modify_thumb_page,
|
|
# 'price_modification': modify_price_page,
|
|
# 'title_modification': modify_product_title,
|
|
# }
|
|
|
|
def should_execute_step(step_name, login_info):
|
|
if step_name == 'tag_modification':
|
|
return login_info.whether_modifyProductTag
|
|
elif step_name == 'thumbnail_modification':
|
|
return login_info.whether_modifyProductThumb
|
|
elif step_name == 'option_modification':
|
|
return login_info.whether_modifyProductOptions
|
|
elif step_name == 'detail_page_modification':
|
|
return login_info.whether_modifyProductDetail
|
|
elif step_name == 'price_modification':
|
|
return login_info.whether_modifyProductPrice
|
|
else:
|
|
return True
|
|
|
|
def perform_step(db, step_name, action, current_user, *args):
|
|
"""
|
|
단계별 작업을 수행하는 함수.
|
|
"""
|
|
product_info = args[1]
|
|
try:
|
|
action(*args) # action 함수에 product_info 및 *args를 전달합니다.
|
|
db.update_process_step(product_info.id, step_name, current_user)
|
|
logger.debug(f"Step {step_name} completed for product {product_info.id}.")
|
|
except Exception as e:
|
|
logger.error(f"Error performing step {step_name} for product {product_info.id}: {e}", exc_info=True)
|
|
|
|
|
|
def load_json_naver_codes(filename):
|
|
codes = []
|
|
with open(filename, "r", encoding='utf-8') as file:
|
|
for line in file:
|
|
try:
|
|
item = json.loads(line)
|
|
codes.append(item)
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"Error decoding JSON: {e}", exc_info=True)
|
|
return codes
|
|
|
|
def wait_for_javascript(driver, timeout=20):
|
|
try:
|
|
WebDriverWait(driver, timeout).until(lambda d: d.execute_script('return document.readyState') == 'complete')
|
|
except TimeoutException:
|
|
logger.debug("페이지 로딩 실패: 시간 초과")
|
|
|
|
def modify_products(driver, gemini, mongo_config, login_info, set_num_modify):
|
|
# product_info = set_product_info() # 상품정보리스트 생성
|
|
autoPercentyProductsDB = AutoPercentyProductsDB(mongo_config)
|
|
|
|
autoPercentyProductsDB.reset_product_by_id('660d636271e50111cf71284e')
|
|
autoPercentyProductsDB.reset_product_by_id('660d635371e50111cf712842')
|
|
|
|
try:
|
|
if login_info['per_mode']:
|
|
current_user = login_info['per_email']
|
|
else:
|
|
current_user = login_info['per_em_email']
|
|
|
|
logger.debug(f"현재 작업중인 사용자 지정 : {current_user}")
|
|
except Exception as e:
|
|
logger.debug(f"현재 작업중인 사용자 지정 중 에러발생 : {e}", exc_info=True)
|
|
|
|
|
|
# MongoDB에 연결
|
|
try:
|
|
client = mongo_config.client
|
|
# self.login_db = self.mongoConfig.get_db() # mongo_config 인스턴스를 통해 데이터베이스 객체를 가져옴
|
|
db = client['taobao_project']
|
|
# products_collection = db['AutoPercenty_Produtcs']
|
|
delv_collection = db['delv_fee']
|
|
except Exception as e:
|
|
logger.debug(f"DB연결 중 에러발생 : {e}", exc_info=True)
|
|
|
|
set_num_modify = int(set_num_modify)
|
|
logger.debug(f"수정대상 상품 수 설정 : {set_num_modify}")
|
|
|
|
# 한 번만 호출하여 메모리에 로드
|
|
json_naver_codes = load_json_naver_codes("Percenty_SS_code.json")
|
|
|
|
# 총 상품 수 확인을 위해 모든 자바스크립트가 로드 될때까지 기다리기
|
|
logger.debug("모든 JS 로드 대기")
|
|
wait_for_javascript(driver)
|
|
logger.debug("총 상품 수 확인을 위한 JS 로드 완료")
|
|
|
|
# 총 상품 수 확인
|
|
try:
|
|
total_products_element = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.XPATH, "//span[contains(.,'총')]"))
|
|
)
|
|
total_products_text = total_products_element.text
|
|
total_products = int(''.join(filter(str.isdigit, total_products_text)))
|
|
logger.debug(f"총 상품수 : {total_products}")
|
|
total_pages = (total_products + 19) // 20
|
|
except Exception as e:
|
|
logger.debug(f"총 상품 수 확인 중 오류 발생: 요소를 찾을 수 없습니다.{e}", exc_info=True)
|
|
|
|
if set_num_modify == 0:
|
|
pass
|
|
else:
|
|
total_products = set_num_modify
|
|
logger.debug(f"수정 대상 상품수 재설정 : {total_products}")
|
|
|
|
current_page = 1
|
|
completed_products = 0
|
|
|
|
product_infos = []
|
|
|
|
|
|
while current_page <= total_pages:
|
|
# 현재 페이지의 상품 수 계산
|
|
products_on_page = min(20, total_products - completed_products)
|
|
|
|
for i in range(1, products_on_page + 1):
|
|
# try:
|
|
logger.debug(f"{current_page}페이지-{i}번 상품 수정시작")
|
|
product_infos.append(ProductInfo())
|
|
# 1번 상품과 나머지 상품들에 대한 XPATH 처리
|
|
|
|
steps_and_actions = [
|
|
('tag_modification', edit_tag, (driver, product_infos[i-1])),
|
|
('thumbnail_modification', modify_thumb_page, (driver, product_infos[i-1])),
|
|
('option_modification', modify_option_page, (driver, product_infos[i-1])),
|
|
('detail_page_modification', modify_detail_page, (driver, product_infos[i-1], gemini, delv_collection, json_naver_codes)),
|
|
('price_modification', modify_price_page, (driver, product_infos[i-1])),
|
|
('title_modification', modify_product_title, (driver, product_infos[i-1])),
|
|
('trans_detailImage', tran_detail_image, (driver, product_infos[i-1])),
|
|
('upload_to_market', upload_to_market, (driver, product_infos[i-1])),
|
|
]
|
|
|
|
# 상품 수정 관련 작업을 조건에 따라 수행하는 로직
|
|
step_conditions = {
|
|
'tag_modification': login_info.whether_modifyProductTag,
|
|
'thumbnail_modification': login_info.whether_modifyProductThumb,
|
|
'option_modification': login_info.whether_modifyProductOptions,
|
|
'detail_page_modification': login_info.whether_modifyProductDetail,
|
|
'price_modification': login_info.whether_modifyProductPrice,
|
|
'title_modification': login_info.whether_modifyProductName,
|
|
'trans_detailImage': login_info.whether_modifyImageTanslation,
|
|
'upload_to_market': login_info.whether_uploadToMarket,
|
|
}
|
|
|
|
# 상품ID 복사
|
|
try:
|
|
product_id_element = return_element(driver,"XPATH",f"//div[{i}]/li/div/div/div[2]/div/div/div/div[3]/div[3]/span[2]/span",10)
|
|
product_id = product_id_element.get_attribute('innerText')
|
|
# product_id = f"ID:{product_id}"
|
|
product_infos[i-1].id = product_id
|
|
logger.debug(f"상품ID : {product_id}")
|
|
except Exception as e:
|
|
logger.debug(f"상품ID 복사 중 오류 발생: 요소를 찾을 수 없습니다. : {e}", exc_info=True)
|
|
|
|
|
|
# 상품ID 처리 여부 판단
|
|
|
|
incomplete_steps = autoPercentyProductsDB.is_step_incomplete(product_id)
|
|
|
|
if incomplete_steps is True:
|
|
pass
|
|
elif isinstance(incomplete_steps, list) and len(incomplete_steps) < 6:
|
|
# incomplete_steps가 리스트 타입이고, 길이가 6 미만인 경우에만 미완성된 단계들에 대해 처리합니다.
|
|
logger.debug(f"총 [{len(incomplete_steps)}]개의 미완성 목록을 발견")
|
|
logger.debug(f"미완성 스텝 목록 : {incomplete_steps}")
|
|
product_infos[i-1] = autoPercentyProductsDB.get_product_info_by_id(product_id)
|
|
logger.debug("기존 product_info를 가져옵니다.")
|
|
# 완료되지 않은 단계에 해당하는 작업을 수행합니다.
|
|
click_to_product_title_for_modify_xpath = f"//div[{i}]/li/div/div/div[2]/div/div/div/div"
|
|
click_element(driver, 'XPATH', click_to_product_title_for_modify_xpath, 10, 'js')
|
|
logger.debug("상품 수정 페이지 클릭")
|
|
time.sleep(2)
|
|
for step_name, action, args in steps_and_actions:
|
|
if step_name in incomplete_steps:
|
|
# 각 단계별 실행 여부 판단
|
|
if step_conditions.get(step_name, False):
|
|
perform_step(autoPercentyProductsDB, step_name, action, current_user, *args)
|
|
autoPercentyProductsDB.finalize_product_processing(product_id, current_user, product_infos[i-1])
|
|
logger.info(f"상품 ID {product_id}의 미완성 목록을 완성했습니다.")
|
|
pass
|
|
else:
|
|
# 여기에는 incomplete_steps가 False이거나 리스트의 길이가 6인 경우.
|
|
# 이는 상품이 수정된 적 없거나 모든 단계가 미완성인 상태를 의미.
|
|
autoPercentyProductsDB.initialize_process_steps(product_id, current_user)
|
|
logger.info(f"상품 ID {product_id}를 초기화 하고 상품수정을 시작합니다.")
|
|
|
|
try:
|
|
p_main_title_xpath = f"//div[{i}]/li/div/div/div[2]/div/div/div[1]/div[1]/span[2]"
|
|
# p_main_title_xpath = f"//div[{i}]/li/div/div/div[2]/div/div/div/div/span"
|
|
p_main_title_element = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.XPATH, p_main_title_xpath))
|
|
)
|
|
p_main_title_text = p_main_title_element.text
|
|
if not p_main_title_text:
|
|
logger.debug("상품명 다시 가져오기")
|
|
p_main_title_text = p_main_title_element.get_attribute('innerHTML').strip()
|
|
product_infos[i-1].keyword_title = p_main_title_text
|
|
logger.debug(f"상품명 확인 : {p_main_title_text}")
|
|
if p_main_title_text == "수집 오류 발생":
|
|
logger.debug("수집 오류 발생한 상품은 건너뜁니다.")
|
|
continue # 다음 상품으로 넘어감
|
|
# 여기서부터는 "상품명"이 확인되었거나, 다른 조건에 해당하는 경우 상품 수정 로직을 계속 진행합니다.
|
|
except Exception as e:
|
|
logger.debug(f"상품명 확인 중 오류 발생: {e}", exc_info=True)
|
|
continue # 해당 상품을 건너뛰고 다음 상품으로 넘어감
|
|
|
|
# if i == 1:
|
|
# xpath_pattern = f"//div[3]/div/span[2]"
|
|
|
|
# # 1번상품 xpath=//div[3]/div/span[2]
|
|
# # 2번상품 xpath=//div[2]/li/div/div/div[2]/div/div/div/div[3]/div/span[2]
|
|
# # 3번상품 xpath=//div[3]/li/div/div/div[2]/div/div/div/div[3]/div/span[2]
|
|
# # 20번상품 xpath=//div[20]/li/div/div/div[2]/div/div/div/div[3]/div/span[2]
|
|
# else:
|
|
# # xpath_pattern = f"//div[2]/li[{i}]/div/div/div[2]/div/div/div/div[3]/div/span[2]"
|
|
# xpath_pattern = f"//div[{i}]/li/div/div/div[2]/div/div/div/div[3]/div/span[2]"
|
|
|
|
|
|
try:
|
|
xpath_pattern = f"//div[{i}]/li/div/div/div[2]/div/div/div[1]/div[3]/div[1]/span[2]"
|
|
product_tao_price_element = driver.find_element(By.XPATH, xpath_pattern)
|
|
product_tao_price = product_tao_price_element.text
|
|
logger.debug(f"product_tao_price : {product_tao_price}")
|
|
|
|
# pattern = r'¥(\d+)~(\d+)'
|
|
# pattern = r'¥(\d{1,3}(?:,\d{3})*)~(\d{1,3}(?:,\d{3})*)'
|
|
# pattern = r'¥(\d{1,3}(?:,\d{3})*|\d+\.\d+)~(\d{1,3}(?:,\d{3})*|\d+\.\d+)'
|
|
# 범위 또는 단일 값을 추출하기 위한 패턴 수정
|
|
pattern = r'¥(\d{1,3}(?:,\d{3})*|\d+\.\d+)(?:~(\d{1,3}(?:,\d{3})*|\d+\.\d+))?'
|
|
|
|
match = re.search(pattern, product_tao_price)
|
|
|
|
if match:
|
|
if match.group(2): # 범위의 두 번째 값이 존재하는 경우
|
|
# 쉼표를 제거하고, 첫 번째 값 올림 처리
|
|
product_low_cost = math.ceil(float(match.group(1).replace(',', '')))
|
|
# 쉼표를 제거하고, 두 번째 값 올림 처리
|
|
product_high_cost = math.ceil(float(match.group(2).replace(',', '')))
|
|
else: # 단일 값만 존재하는 경우
|
|
product_low_cost = math.ceil(float(match.group(1).replace(',', '')))
|
|
product_high_cost = product_low_cost # 저가와 고가 모두 같은 값 할당
|
|
|
|
logger.debug(f"낮은 원가 : {product_low_cost}")
|
|
logger.debug(f"높은 원가 : {product_high_cost}")
|
|
|
|
else:
|
|
logger.debug("상품 원가 수집 오류 발생: 요소를 찾을 수 없습니다.")
|
|
logger.debug("원가를 기본값으로 할당합니다.")
|
|
product_low_cost = 100
|
|
product_high_cost = 100
|
|
|
|
product_infos[i-1].tao_low_price = product_low_cost
|
|
product_infos[i-1].tao_high_price = product_high_cost
|
|
except Exception as e:
|
|
logger.debug(f"상품 상세 정보 수집 중 오류 발생: {e}", exc_info=True)
|
|
|
|
# 상품 이미지 복사
|
|
try:
|
|
product_image_element = return_element(driver,"XPATH",f"//div[{i}]/li/div/div/div[1]/div/div[2]/div/div/img",10)
|
|
except Exception as e:
|
|
logger.debug(f"상품 이미지 URL 복사 중 오류 발생: 요소를 찾을 수 없습니다. : {e}", exc_info=True)
|
|
product_image_url = product_image_element.get_attribute('src')
|
|
product_infos[i-1].main_image_url = product_image_url
|
|
logger.debug(f"product_image_url : {product_image_url}")
|
|
|
|
|
|
# 상품 수정 시작
|
|
# try:
|
|
# product_title_element = WebDriverWait(driver, 10).until(
|
|
# EC.presence_of_element_located((By.XPATH, (f"//div[{i}]/li/div/div/div[2]/div/div/div/div")))
|
|
# # EC.presence_of_element_located((By.CSS_SELECTOR, ".signList > .ant-btn-default > span"))
|
|
|
|
# )
|
|
# except Exception as e:
|
|
# logger.debug(f"상품 수정시작 중 오류 발생: 요소를 찾을 수 없습니다.{e}", exc_info=True)
|
|
|
|
# # product_title_element = driver.find_element(By.XPATH, (f"//div[{i}]/li/div/div/div[2]/div/div/div/div"))
|
|
# driver.execute_script("arguments[0].click();", product_title_element)# 상품 수정 페이지 자바스크립트로 열기
|
|
|
|
click_to_product_title_for_modify_xpath = f"//div[{i}]/li/div/div/div[2]/div/div/div/div"
|
|
click_element(driver, 'XPATH', click_to_product_title_for_modify_xpath, 10, 'js')
|
|
logger.debug("상품 수정 페이지 클릭")
|
|
time.sleep(0.3)
|
|
|
|
|
|
tao_title_text_xpath = "//div[@id='productMainContentContainerId']/div/div/div[6]/div/div/span"
|
|
tao_title = return_element(driver, 'XPATH', tao_title_text_xpath, 10)
|
|
logger.debug(f"tao_title 텍스트 : {tao_title.text}")
|
|
product_infos[i-1].tao_title = tao_title.text
|
|
|
|
# 상품수정 페이지에 표시된 퍼센티카테고리 텍스트 수집
|
|
per_cat = return_element(driver, 'XPATH', '//div[8]/div/div/div[2]/div/div/div/span[2]/div/div', 10)
|
|
logger.debug(f"퍼센티 등록 화면에 표시된 카테고리 텍스트 : {per_cat.text}")
|
|
product_infos[i-1].per_cat_code = per_cat.text
|
|
|
|
|
|
# # 이미지 주소 복사
|
|
# # image_element = driver.find_element(By.XPATH, "//div[@id='productMainContentContainerId']/div/div/div/div/div[2]/div/img")
|
|
# try:
|
|
# image_element = WebDriverWait(driver, 10).until(
|
|
# # EC.presence_of_element_located((By.CSS_SELECTOR, ".sc-gFnajm"))
|
|
# EC.presence_of_element_located((By.CSS_SELECTOR, ".sc-iaJaUu"))
|
|
|
|
# )
|
|
# except Exception as e:
|
|
# logger.debug(f"상품 이미지 주소 중 오류 발생: 요소를 찾을 수 없습니다. : {e}", exc_info=True)
|
|
# # image_element = driver.find_element(By.CSS_SELECTOR, ".sc-gFnajm")
|
|
# image_src = image_element.get_attribute("src")
|
|
# logger.debug(f"상품 이미지 주소 : {image_src}")
|
|
|
|
# #상품명 복사
|
|
# product_title_element = driver.find_element(By.XPATH, "//div[@id='productMainContentContainerId']/div/div/div/div/div[5]/div/span/input")
|
|
# # product_title_element = driver.find_element(By.CSS_SELECTOR, ".ant-input-affix-wrapper-focused > .ant-input")
|
|
# try:
|
|
# product_title_element = WebDriverWait(driver, 10).until(
|
|
# EC.presence_of_element_located((By.XPATH, "//div[5]/div/span/input"))
|
|
# )
|
|
# except Exception as e:
|
|
# logger.debug(f"상품명 복사 중 오류 발생: 요소를 찾을 수 없습니다. : {e}", exc_info=True)
|
|
# # product_title_element = driver.find_element(By.XPATH, "//div[5]/div/span/input")
|
|
# product_title = product_title_element.get_attribute("value")
|
|
|
|
product_infos[i-1].main_image_url = product_image_url
|
|
|
|
# 각 단계별로 수정 작업 수행
|
|
|
|
for step_name, action, args in steps_and_actions:
|
|
# 각 단계별 실행 여부 판단
|
|
if step_conditions.get(step_name, False):
|
|
perform_step(autoPercentyProductsDB, step_name, action, current_user, *args)
|
|
|
|
# 모든 단계가 완료되었다면, 상품 처리 최종화
|
|
autoPercentyProductsDB.finalize_product_processing(product_infos[i-1].id, current_user, product_infos[i-1])
|
|
|
|
# try:
|
|
# # 각 단계별 작업 수행
|
|
# perform_step(autoPercentyProductsDB, 'tag_modification', product_infos[i-1], current_user, driver)
|
|
# perform_step(autoPercentyProductsDB, 'option_modification', product_infos[i-1], current_user, driver)
|
|
# perform_step(autoPercentyProductsDB, 'detail_page_modification', product_infos[i-1], current_user, driver, gemini, delv_collection, json_naver_codes)
|
|
# perform_step(autoPercentyProductsDB, 'thumbnail_modification', product_infos[i-1], current_user, driver)
|
|
# perform_step(autoPercentyProductsDB, 'price_modification', product_infos[i-1], current_user, driver)
|
|
# logger.debug("모든 단계의 수정 작업이 완료되었습니다.")
|
|
# except Exception as e:
|
|
# logger.error(f"수정 작업 중 예외 발생: {e}", exc_info=True)
|
|
|
|
# logger.debug("키워드 수정작업 시작")
|
|
# edit_tag(driver, product_infos[i-1])
|
|
# autoPercentyProductsDB.update_process_step(product_id, step_name="step1")
|
|
# logger.debug("키워드 수정작업 완료")
|
|
|
|
# logger.debug("옵션 수정작업 시작")
|
|
# modify_option_page(driver, product_infos[i-1])
|
|
# logger.debug("옵션 수정작업 완료")
|
|
|
|
# # 상품 수정 작업 수행
|
|
# logger.debug("상세페이지 수정작업 시작")
|
|
# modify_detail_page(driver, gemini, product_infos[i-1], delv_collection, json_naver_codes)
|
|
# logger.debug("상세페이지 수정작업 완료")
|
|
|
|
# logger.debug("썸네일 수정작업 시작")
|
|
# modify_thumb_page(driver, product_infos[i-1])
|
|
# logger.debug("썸네일 수정작업 완료")
|
|
|
|
# logger.debug("가격 수정작업 시작")
|
|
# modify_price_page(driver, product_infos[i-1])
|
|
# logger.debug("가격 수정작업 완료")
|
|
|
|
# logger.debug("상품명 수정작업 시작")
|
|
# # modify_product_title(driver, product_infos[i-1])
|
|
# logger.debug("......상품명 메서드 작성 중......")
|
|
# logger.debug("상품명 수정작업 완료")
|
|
|
|
|
|
# 상품수정페이지 저장 버튼 클릭
|
|
logger.debug("상품 수정 저장 중......")
|
|
click_element(driver, 'CSS_SELECTOR', '.ant-col:nth-child(9) > .ant-btn', wait_time=10, click_type='js')
|
|
|
|
# 상품수정페이지 닫기 버튼 클릭
|
|
time.sleep(1)
|
|
ActionChains(driver).send_keys(Keys.ESCAPE).perform()
|
|
|
|
|
|
logger.debug(f"상품 {product_id} 처리 완료.")
|
|
completed_products += 1
|
|
|
|
logger.debug(f"진행 상황: {completed_products}/{total_products} ({(completed_products/total_products)*100:.2f}%)")
|
|
|
|
# except Exception as e:
|
|
# logger.debug(f"상품 {i} 확인 중 오류 발생: {e}", exc_info=True)
|
|
|
|
# 다음 페이지로 이동
|
|
if current_page < total_pages:
|
|
try:
|
|
next_page_button = WebDriverWait(driver, 10).until(
|
|
EC.presence_of_element_located((By.CSS_SELECTOR, ".ant-pagination-next > .ant-pagination-item-link"))
|
|
)
|
|
# next_page_button = driver.find_element(By.CSS_SELECTOR, ".ant-pagination-next > .ant-pagination-item-link")
|
|
# next_page_button.click()
|
|
driver.execute_script("arguments[0].click();", next_page_button)
|
|
|
|
time.sleep(2)
|
|
current_page += 1
|
|
except Exception as e:
|
|
logger.debug(f"다음 페이지로 이동하는 중 오류 발생: {e}", exc_info=True)
|
|
break
|
|
else:
|
|
logger.debug("모든 페이지 처리 완료. 작업 종료.")
|
|
break
|
|
|
|
logger.debug("상품 수정 작업이 완료되었습니다.")
|