TaoSourcerer/modules/automatch_tao.py

216 lines
10 KiB
Python

import time, re
from random import randint
import sqlite3
import pandas as pd
from modules.tao_parser import setup_driver, login_and_manage_session, fetch_and_save_taobao_products
from modules.aii import generate_image_description
import logging
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
def automatch(db, item_count, message_controller, sort_order, progress_callback=None):
logger.debug(f"automatch Start 변수 : [DB] - {db}, [item_count] - {item_count}, [sort_order] - {sort_order}")
# 데이터베이스에서 필요한 데이터 로드
conn = sqlite3.connect(db)
cursor = conn.cursor()
# Test Query to ensure DB connection is working
cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
tables = cursor.fetchall()
logger.debug(f"Available tables: {tables}") # Print available tables to check DB connection
query = "SELECT * FROM NaverShopping" # Keywords 테이블에서 모든 데이터를 선택하는 쿼리문
cursor.execute(query)
rows = cursor.fetchall()
if rows:
logger.debug(f"쿼리 실행 성공. 가져온 행의 수: {len(rows)}")
else:
logger.debug("쿼리는 실행되었지만 가져온 행이 없습니다. 테이블이 채워져 있는지 확인하세요.")
df_NS = pd.read_sql_query(query, conn)
logger.debug(f"df_NS : {df_NS}")
# keyword_id별로 그룹화
# df_NS.sort_values('keyword_id', inplace=True) # keyword_id 기준으로 정렬
grouped = df_NS.groupby('keyword_id')
logger.debug(f"grouped_df_NS : {grouped}")
# 전체 keyword_id 그룹의 수
total_groups = len(grouped)
logger.debug(f"total_groups Number : {total_groups}")
driver = setup_driver()
logger.debug("셀레니움 드라이버 설정 완료")
login_and_manage_session(driver)
logger.debug("셀레니움 로그인 세션 완료")
index = 0
# for keyword_id, group in grouped:
for idx, (keyword_id, group) in enumerate(grouped): # 인덱스 추가하여 반복
# 진행 상황 업데이트
if progress_callback:
progress_callback(idx + 1, total_groups)
# 현재 keyword_id 그룹의 첫 번째 row를 가져옴
first_row = group.iloc[0]
# 해당 row의 id를 기반으로 rows에서 MatchingUrl 검사
matching_url = first_row['MatchingUrl']
logger.debug(f"선택된 matching_url : [{matching_url}]")
# MatchingUrl이 존재하는지 검사
if matching_url: # MatchingUrl 컬럼에 값이 존재하면
logger.debug(f"keyword_id {keyword_id}는 이미 처리되었습니다. 스킵합니다.")
continue
# logger.debug(f"선택된 그룹의 첫번째 열의 matching_url[0] : {aaaa}")
logger.debug(f"현재 keyword_id : {keyword_id}")
logger.debug(f"keyword_id {idx}/{total_groups} 처리시작")
per = (int(idx)/total_groups) * 100
logger.debug(f"========== 진행률 [{per}%] ==========")
imgurl = group['imageUrl'].iloc[0] # 현재 keyword_id의 imgurl
main_keyword = group.iloc[0]['keyword'] # 메인 키워드
naver_ids = group['id'].tolist() # 현재 keyword_id에 해당하는 NaverShopping id 리스트
average_price = group['price'].mean()
# fetch_and_save_taobao_products 함수 호출 전에 랜덤한 시간 동안 대기
sleep_time_before = randint(1, 3)
logger.debug(f"호출 전 {sleep_time_before}초 동안 대기합니다.")
time.sleep(sleep_time_before)
products = [] # 타오서칭함수 호출 전 초기화
# fetch_and_save_taobao_products 함수 호출
# products = fetch_and_save_taobao_products(driver, imgurl, item_count=len(group), sort_order=1)
products = fetch_and_save_taobao_products(driver, message_controller, imgurl, cursor, db, item_count=5, sort_order=1)
products_count = len(products)
logger.debug(f"가져온 products_count : {products_count}")
# logger.debug(f"automatch - for 구문 내 fetch_and_save_taobao_products 완료 후 리턴된 products : {products}")
try:
for i, product in enumerate(products):
logger.debug(f"{i}번째 product 정보 DB 업데이트 준비")
itemUrl, itemID, imageUrl, item_name, price, sales_volume = product
# DB에 상품 정보 업데이트
update_query = """
INSERT INTO Taobao (keyword_id, itemUrl, itemID, imageUrl, item_name, price, sales_volume)
VALUES (?, ?, ?, ?, ?, ?, ?)
"""
#logger.debug(f"DB 정보 업데이트 쿼리 설정 : {update_query}")
cursor.execute(update_query, (keyword_id, itemUrl, itemID, imageUrl, item_name, price, sales_volume))
logger.debug(f"TaoBao 테이블에 [{product}/{len(products)}] 내용 업데이트 실행")
except Exception as e:
logger.debug(f"product 정보 DB 업데이트 중 오류 발생 : {e}", exc_info=True)
logger.debug(f"{len(products)}개의 product 정보 DB 업데이트 완료")
conn.commit()
# 현재 keyword_id에 대한 products 개수
product_count = len(group)
# 각 row에 대해 업데이트 수행
# for (index, row), product in zip(group.iterrows(), products[:len(group)]):
# for index, (row, product) in enumerate(zip(group.itertuples(index=False), products)):
# for index, (row, product) in enumerate(zip(group.iterrows(), products[:product_count])):
for index, (row, product) in enumerate(zip(group.itertuples(index=False), products[:product_count])):
# itemUrl, itemID, imageUrl, item_name, price, sales_volume = product # 튜플일때
# 상품 정보 추출 #리스트일때
itemUrl = product['Product URL']
itemID = product['Tao_itemID']
imageUrl = product['Image URL']
item_name = product['Product Name']
price = product['Price']
sales_volume = product['Sales Volume']
if price == '' and itemID =='':
continue
if keyword_id != row.keyword_id:
continue
# ns_id = row['id']
# ns_id = row.id
ns_id = naver_ids[index]
# 자동매칭 정보 준비
# cat_code = row['cat_code']
# cat_code = row.cat_code # 수정된 부분
cat_code = row.cat_code if row.cat_code is not None else ""
# categories = [row['category1Name'], row['category2Name'], row['category3Name'], row['category4Name']]
categories = [row.category1Name, row.category2Name, row.category3Name, row.category4Name] # 수정된 부분
combined_category = '-'.join(filter(None, categories))
final_category = cat_code + " " + combined_category
# 배송비, 포장비, 마진 기본정보 준비
# av = average_price
# won_price = price * 190
# cost = (won_price*1.035) * 1.13
# delvfee = av - (cost * 1.25)
temp_delvFee = check_delvFee(imgurl)
delvFee = 10000 if not temp_delvFee or not isinstance(temp_delvFee, int) else temp_delvFee
plusFee = 5000 if float(price) < 200 else 10000 if float(price) < 400 else str(5000 + int((price - 200) / 200) * 10000)
packingFee = 2000
# PC 주소 생성
match = re.search(r'taobao.com/i(\d{10,12})', itemUrl)
pc_url = f"https://item.taobao.com/item.htm?id={match.group(1)}" if match else ""
# NaverShopping 테이블에 매칭 정보 업데이트
update_ns_query = """
UPDATE NaverShopping
SET MatchingCat = ?, delvFee = ?, packingFee = ?, plusFee = ?, MatchingUrl = ?, tao_imageUrl = ?, tao_itemID = ?
WHERE id = ?
"""
if row.keyword != "-" and index == 0:
logger.debug(f"첫 번째 상품 업데이트 실행: {row.keyword}")
cursor.execute(update_ns_query, (final_category, delvFee, packingFee, plusFee, pc_url, imageUrl, itemID, ns_id))
conn.commit()
logger.debug(f"NaverShopping id {ns_id} 업데이트 완료: {itemUrl}, {itemID}, {imageUrl}, {item_name}, {price}, {sales_volume}")
else:
# 이후 인덱스에 대해서는 기존 조건에 따라 업데이트를 결정
if row.keyword != "-" and row.keyword != main_keyword:
logger.debug(f"추가 키워드 업데이트 실행: {row.keyword}")
cursor.execute(update_ns_query, (final_category, delvFee, packingFee, plusFee, pc_url, imageUrl, itemID, ns_id))
conn.commit()
logger.debug(f"NaverShopping id {ns_id} 업데이트 완료: {itemUrl}, {itemID}, {imageUrl}, {item_name}, {price}, {sales_volume}")
else:
logger.debug(f"NaverShopping id {ns_id} 업데이트 생략: {row.keyword}")
# # 메인 키워드 업데이트 조건 검사 및 적용
# if index == 0 or row.keyword != "-" or row.keyword != main_keyword:
# logger.debug(f"row.keyword : {row.keyword}")
# # 첫 번째 상품(메인 키워드) 또는 메인 키워드와 다른 추가 키워드에 대한 업데이트 실행
# cursor.execute(update_ns_query, (final_category, delvFee, packingFee, plusFee, pc_url, imageUrl, itemID, ns_id))
# conn.commit()
# logger.debug(f"NaverShopping id {ns_id} 업데이트 완료: {itemUrl}, {itemID}, {imageUrl}, {item_name}, {price}, {sales_volume}")
# elif row.keyword == main_keyword or row.keyword == "-":
# logger.debug(f"row.keyword : {row.keyword}")
# # 메인 키워드와 동일할 경우 업데이트 생략
# logger.debug(f"NaverShopping id {ns_id} 업데이트 생략: 메인 키워드와 동일")
# index = index + 1
logger.debug("모든 keyword_id에 대한 업데이트 완료")
driver.quit()
logger.debug("셀레니움 driver 종료")
conn.close() # DB 연결 종료
logger.debug("DB Connect 종료")
def check_delvFee(imgurl):
return None