캡차 세분류, log함수 잘못된 사용 수정
This commit is contained in:
parent
c856ce4045
commit
844366938d
|
|
@ -36,6 +36,90 @@ import logging
|
|||
# 로거 인스턴스 가져오기
|
||||
logger = logging.getLogger('default_logger')
|
||||
|
||||
def convert_price(price_str):
|
||||
logger.debug(f"convert_price : {price_str}")
|
||||
|
||||
try:
|
||||
return int(float(price_str))
|
||||
except ValueError:
|
||||
return 0
|
||||
|
||||
def convert_sales_volume(sales_str):
|
||||
logger.debug(f"convert_sales_volume : {sales_str}")
|
||||
match = re.search(r'(\d+)(万)?\+?', sales_str)
|
||||
if match:
|
||||
num = int(match.group(1))
|
||||
if match.group(2): # '万'이 포함되어 있다면
|
||||
num *= 10000 # 万은 10,000을 의미
|
||||
return num
|
||||
else:
|
||||
return 0
|
||||
|
||||
def extract_item_id(url):
|
||||
logger.debug(f"extract_item_id : {url}")
|
||||
match = re.search(r'taobao.com/i(\d{10,12})', url)
|
||||
return match.group(1) if match else None
|
||||
|
||||
def fetch_products(souped, item_count, products, similarity_threshold):
|
||||
for i, product in enumerate(souped, start=1):
|
||||
logger.debug(f"souped product {i} \n {souped}")
|
||||
if i > item_count: # 설정한 아이템 갯수에 도달하면 반복 중단
|
||||
break
|
||||
try:
|
||||
product_url = product['href']
|
||||
logger.debug(f"타오바오 상품 product_url : {product_url}")
|
||||
Tao_itemID = extract_item_id(product_url)
|
||||
logger.debug(f"타오바오 상품 extract_item_id : {Tao_itemID}")
|
||||
image_url = 'https:' + product.select_one("img")['src']
|
||||
logger.debug(f"타오바오 상품 image_url : {image_url}")
|
||||
product_name = product.select_one("span.mobile--summary--2mK9e7G").text
|
||||
logger.debug(f"타오바오 상품 product_name : {product_name}")
|
||||
#trans_product_name = trans(product_name)
|
||||
trans_product_name = translate_texts_translatepy(product_name)
|
||||
trans_product_name = str(trans_product_name)
|
||||
logger.debug(f"타오바오 상품 trans_product_name : {trans_product_name}")
|
||||
price_str = product.select_one("span.mobile--price--3eMQ3ec").text
|
||||
logger.debug(f"타오바오 상품 price_str : {price_str}")
|
||||
price = convert_price(price_str)
|
||||
sales_volume_str = product.select_one("span.mobile--buy--2I4hwR4").text
|
||||
logger.debug(f"타오바오 상품 sales_volume_str : {sales_volume_str}")
|
||||
sales_volume = convert_sales_volume(sales_volume_str)
|
||||
logger.debug(f"타오바오 상품 sales_volume : {sales_volume}")
|
||||
|
||||
# =============================
|
||||
# 이미지 유사도 검사부분 개선필요. 현재는 삭제
|
||||
# 이미지 유사도 검사
|
||||
# logger.debug("이미지 유사도 검사 실행")
|
||||
# logger.debug(f"원본이미지 : {imgurl}")
|
||||
# logger.debug(f"타켓이미지 : {image_url}")
|
||||
# difference = compare_images_phash(imgurl, image_url)
|
||||
# logger.debug(f"이미지 유사도 difference = {difference}/{similarity_threshold}")
|
||||
# ==============================
|
||||
|
||||
difference = 30
|
||||
# wait=randint(1,4)
|
||||
# time.sleep(wait) # 또는 더 긴 시간
|
||||
# logger.debug(f"요청간 TimeSleep : {wait}")
|
||||
|
||||
|
||||
if difference <= similarity_threshold:
|
||||
logger.debug(f"상품 [{Tao_itemID}]의 상품정보 추가")
|
||||
product_info = {
|
||||
"Product Name": trans_product_name,
|
||||
"Image URL": image_url,
|
||||
"Price": price,
|
||||
"Sales Volume": sales_volume,
|
||||
"Product URL": product_url,
|
||||
"Tao_itemID": Tao_itemID,
|
||||
}
|
||||
else:
|
||||
logger.debug(f"상품 [{Tao_itemID}]의 상품이미지가 일치하지 않아 제외처리")
|
||||
|
||||
products.append(product_info)
|
||||
except Exception as e:
|
||||
logger.debug(f"상품정보 추출 오류 발생 {i}: {e}")
|
||||
|
||||
|
||||
|
||||
def translate_texts_translatepy(text, src_lang='zh-cn', dest_lang='ko'):
|
||||
"""translatepy 라이브러리를 사용하여 텍스트 리스트를 번역합니다."""
|
||||
|
|
@ -64,8 +148,60 @@ def trans(text):
|
|||
except Exception as e:
|
||||
logger.debug(f"번역 중 오류발생 : {e}")
|
||||
|
||||
def check_first_product_tao(driver):
|
||||
try:
|
||||
first_product_CSS = ".rax-view-v2:nth-child(1) > .rax-view-v2 > .mobile--class-1--2Vz4bM4"
|
||||
WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, first_product_CSS)))
|
||||
logger.debug("첫번째 상품을 찾았습니다.")
|
||||
return True
|
||||
except TimeoutException:
|
||||
logger.debug("오류 : 첫번째 상품을 찾을 수 없습니다.")
|
||||
return False
|
||||
|
||||
def handle_captcha_for_tao(driver, message_controller):
|
||||
captcha_iframe_id = 'baxia-dialog-content'
|
||||
last_message_time = time.time()
|
||||
|
||||
scratch_captcha_class = 'scratch-captcha-question'
|
||||
nocaptcha_class = 'nc_1_nocaptcha'
|
||||
|
||||
try:
|
||||
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.ID, captcha_iframe_id)))
|
||||
logger.debug("CAPTCHA 화면 발생. 진행을 위해 해결하세요")
|
||||
|
||||
# iframe으로 포커스 전환
|
||||
driver.switch_to.frame(captcha_iframe_id)
|
||||
|
||||
# 캡차 유형 식별
|
||||
if driver.find_elements(By.CLASS_NAME, scratch_captcha_class):
|
||||
message_controller.send_message("scratch_captcha 발견: 처리를 기다리고 있습니다.")
|
||||
handle_scratch_captcha(driver) # Scratch captcha 처리를 위한 별도의 함수
|
||||
|
||||
elif driver.find_elements(By.CLASS_NAME, nocaptcha_class):
|
||||
handle_nocaptcha(driver, message_controller, last_message_time) # Nocaptcha 처리를 위한 별도의 함수
|
||||
|
||||
except TimeoutException as e:
|
||||
logger.error(f"CAPTCHA 화면을 찾는 데 실패했습니다: {e}")
|
||||
return False
|
||||
|
||||
finally:
|
||||
# 기본 컨텐츠로 포커스 전환
|
||||
driver.switch_to.default_content()
|
||||
|
||||
|
||||
def handle_scratch_captcha(driver):
|
||||
logger.debug("scratch_captcha 처리 시작")
|
||||
while True:
|
||||
try:
|
||||
if check_first_product_tao(driver):
|
||||
logger.debug("scratch_captcha에서 첫 번째 제품 확인됨: while 문 종료.")
|
||||
break
|
||||
time.sleep(1)
|
||||
except Exception as e:
|
||||
logger.error(f"scratch_captcha에서 check_first_product 처리 중 오류 발생: {e}")
|
||||
break
|
||||
|
||||
def slide_capcha(driver):
|
||||
def handle_nocaptcha(driver):
|
||||
offset = 258
|
||||
driver.switch_to.frame('baxia-dialog-content')
|
||||
print("슬라이딩 시도")
|
||||
|
|
@ -442,8 +578,16 @@ def fetch_and_save_taobao_products(driver, message_controller, imgurl, cursor, d
|
|||
# 캡차 유형 식별
|
||||
if driver.find_elements(By.CLASS_NAME, scratch_captcha_class):
|
||||
message_controller.send_message("scratch_captcha 발견: 처리를 기다리고 있습니다.")
|
||||
logger.debug("scratch_captcha 발견: 처리를 기다리고 있습니다.")
|
||||
while True:
|
||||
time.sleep(1) # 무한 대기
|
||||
try:
|
||||
if check_first_product(driver):
|
||||
logger.debug("scratch_captcha에서 첫 번째 제품 확인됨: while 문 종료.")
|
||||
break # check_first_product가 True일 때 반복 종료
|
||||
time.sleep(1) # 1초 간격으로 확인
|
||||
except Exception as e:
|
||||
logger.error(f"scratch_captcha에서 check_first_product 처리 중 오류 발생: {e}")
|
||||
break # 예외 발생 시 반복 종료
|
||||
|
||||
elif driver.find_elements(By.CLASS_NAME, nocaptcha_class):
|
||||
try:
|
||||
|
|
@ -451,7 +595,7 @@ def fetch_and_save_taobao_products(driver, message_controller, imgurl, cursor, d
|
|||
# message_controller.send_message("CAPTCHA가 발생했습니다. 해결해 주세요.")
|
||||
print("최초 캡챠발생 : 사용자에게 알람 발송")
|
||||
print("nocaptcha 처리 중")
|
||||
slide_capcha(driver)
|
||||
handle_nocaptcha(driver)
|
||||
|
||||
while True:
|
||||
time.sleep(5) # 30초마다 캡차 상태 검사
|
||||
|
|
@ -506,7 +650,8 @@ def fetch_and_save_taobao_products(driver, message_controller, imgurl, cursor, d
|
|||
found_first_product = True
|
||||
break # 첫 번째 상품을 찾았으니 내부 while 루프 탈출
|
||||
else:
|
||||
if handle_captcha(driver, message_controller):
|
||||
# if handle_captcha(driver, message_controller):
|
||||
if handle_captcha_for_tao(driver, message_controller):
|
||||
logger.debug("캡차 화면입니다. 캡차를 해결합니다.")
|
||||
# handle_captcha(driver)
|
||||
elif handle_sorry_message(driver) and refresh_attempts < max_refresh_attempts:
|
||||
|
|
@ -560,64 +705,67 @@ def fetch_and_save_taobao_products(driver, message_controller, imgurl, cursor, d
|
|||
products = [] # 상품 정보를 저장할 리스트
|
||||
similarity_threshold = 40 # 유사도 판단 기준 (해밍 거리)
|
||||
|
||||
# 상품 정보 추출
|
||||
for i, product in enumerate(souped, start=1):
|
||||
logger.debug(f"souped product {i} \n {souped}")
|
||||
if i > item_count: # 설정한 아이템 갯수에 도달하면 반복 중단
|
||||
break
|
||||
try:
|
||||
product_url = product['href']
|
||||
logger.debug(f"타오바오 상품 product_url : {product_url}")
|
||||
Tao_itemID = extract_item_id(product_url)
|
||||
logger.debug(f"타오바오 상품 extract_item_id : {Tao_itemID}")
|
||||
image_url = 'https:' + product.select_one("img")['src']
|
||||
logger.debug(f"타오바오 상품 image_url : {image_url}")
|
||||
product_name = product.select_one("span.mobile--summary--2mK9e7G").text
|
||||
logger.debug(f"타오바오 상품 product_name : {product_name}")
|
||||
#trans_product_name = trans(product_name)
|
||||
trans_product_name = translate_texts_translatepy(product_name)
|
||||
trans_product_name = str(trans_product_name)
|
||||
logger.debug(f"타오바오 상품 trans_product_name : {trans_product_name}")
|
||||
price_str = product.select_one("span.mobile--price--3eMQ3ec").text
|
||||
logger.debug(f"타오바오 상품 price_str : {price_str}")
|
||||
price = convert_price(price_str)
|
||||
sales_volume_str = product.select_one("span.mobile--buy--2I4hwR4").text
|
||||
logger.debug(f"타오바오 상품 sales_volume_str : {sales_volume_str}")
|
||||
sales_volume = convert_sales_volume(sales_volume_str)
|
||||
logger.debug(f"타오바오 상품 sales_volume : {sales_volume}")
|
||||
|
||||
# =============================
|
||||
# 이미지 유사도 검사부분 개선필요. 현재는 삭제
|
||||
# 이미지 유사도 검사
|
||||
# logger.debug("이미지 유사도 검사 실행")
|
||||
# logger.debug(f"원본이미지 : {imgurl}")
|
||||
# logger.debug(f"타켓이미지 : {image_url}")
|
||||
# difference = compare_images_phash(imgurl, image_url)
|
||||
# logger.debug(f"이미지 유사도 difference = {difference}/{similarity_threshold}")
|
||||
# ==============================
|
||||
|
||||
difference = 30
|
||||
# wait=randint(1,4)
|
||||
# time.sleep(wait) # 또는 더 긴 시간
|
||||
# logger.debug(f"요청간 TimeSleep : {wait}")
|
||||
|
||||
|
||||
if difference <= similarity_threshold:
|
||||
logger.debug(f"상품 [{Tao_itemID}]의 상품정보 추가")
|
||||
product_info = {
|
||||
"Product Name": trans_product_name,
|
||||
"Image URL": image_url,
|
||||
"Price": price,
|
||||
"Sales Volume": sales_volume,
|
||||
"Product URL": product_url,
|
||||
"Tao_itemID": Tao_itemID,
|
||||
}
|
||||
else:
|
||||
logger.debug(f"상품 [{Tao_itemID}]의 상품이미지가 일치하지 않아 제외처리")
|
||||
fetch_products(souped, item_count, products, similarity_threshold)
|
||||
|
||||
products.append(product_info)
|
||||
except Exception as e:
|
||||
logger.debug(f"상품정보 추출 오류 발생 {i}: {e}")
|
||||
# # 상품 정보 추출
|
||||
# for i, product in enumerate(souped, start=1):
|
||||
# logger.debug(f"souped product {i} \n {souped}")
|
||||
# if i > item_count: # 설정한 아이템 갯수에 도달하면 반복 중단
|
||||
# break
|
||||
# try:
|
||||
# product_url = product['href']
|
||||
# logger.debug(f"타오바오 상품 product_url : {product_url}")
|
||||
# Tao_itemID = extract_item_id(product_url)
|
||||
# logger.debug(f"타오바오 상품 extract_item_id : {Tao_itemID}")
|
||||
# image_url = 'https:' + product.select_one("img")['src']
|
||||
# logger.debug(f"타오바오 상품 image_url : {image_url}")
|
||||
# product_name = product.select_one("span.mobile--summary--2mK9e7G").text
|
||||
# logger.debug(f"타오바오 상품 product_name : {product_name}")
|
||||
# #trans_product_name = trans(product_name)
|
||||
# trans_product_name = translate_texts_translatepy(product_name)
|
||||
# trans_product_name = str(trans_product_name)
|
||||
# logger.debug(f"타오바오 상품 trans_product_name : {trans_product_name}")
|
||||
# price_str = product.select_one("span.mobile--price--3eMQ3ec").text
|
||||
# logger.debug(f"타오바오 상품 price_str : {price_str}")
|
||||
# price = convert_price(price_str)
|
||||
# sales_volume_str = product.select_one("span.mobile--buy--2I4hwR4").text
|
||||
# logger.debug(f"타오바오 상품 sales_volume_str : {sales_volume_str}")
|
||||
# sales_volume = convert_sales_volume(sales_volume_str)
|
||||
# logger.debug(f"타오바오 상품 sales_volume : {sales_volume}")
|
||||
|
||||
# # =============================
|
||||
# # 이미지 유사도 검사부분 개선필요. 현재는 삭제
|
||||
# # 이미지 유사도 검사
|
||||
# # logger.debug("이미지 유사도 검사 실행")
|
||||
# # logger.debug(f"원본이미지 : {imgurl}")
|
||||
# # logger.debug(f"타켓이미지 : {image_url}")
|
||||
# # difference = compare_images_phash(imgurl, image_url)
|
||||
# # logger.debug(f"이미지 유사도 difference = {difference}/{similarity_threshold}")
|
||||
# # ==============================
|
||||
|
||||
# difference = 30
|
||||
# # wait=randint(1,4)
|
||||
# # time.sleep(wait) # 또는 더 긴 시간
|
||||
# # logger.debug(f"요청간 TimeSleep : {wait}")
|
||||
|
||||
|
||||
# if difference <= similarity_threshold:
|
||||
# logger.debug(f"상품 [{Tao_itemID}]의 상품정보 추가")
|
||||
# product_info = {
|
||||
# "Product Name": trans_product_name,
|
||||
# "Image URL": image_url,
|
||||
# "Price": price,
|
||||
# "Sales Volume": sales_volume,
|
||||
# "Product URL": product_url,
|
||||
# "Tao_itemID": Tao_itemID,
|
||||
# }
|
||||
# else:
|
||||
# logger.debug(f"상품 [{Tao_itemID}]의 상품이미지가 일치하지 않아 제외처리")
|
||||
|
||||
# products.append(product_info)
|
||||
# except Exception as e:
|
||||
# logger.debug(f"상품정보 추출 오류 발생 {i}: {e}")
|
||||
|
||||
|
||||
# # 정렬 로직 (가격순, 판매량순 정렬)
|
||||
|
|
|
|||
|
|
@ -1224,7 +1224,7 @@ class Ui_Dialog(QtWidgets.QDialog):
|
|||
time.sleep(1)
|
||||
|
||||
# 로그에 파일 저장 정보 추가
|
||||
logger.debug(f"로그 '{part_file_name.log}'에 로그데이터가 추가되었습니다.")
|
||||
logger.debug(f"로그 '{part_file_name}'에 로그데이터가 추가되었습니다.")
|
||||
except Exception as e:
|
||||
logger.debug(e)
|
||||
# 예외를 로그에 기록
|
||||
|
|
|
|||
Loading…
Reference in New Issue