diff --git a/ai/deepl_with_playwright.py b/ai/deepl_with_playwright.py
index cfe8d89..c4e90ee 100644
--- a/ai/deepl_with_playwright.py
+++ b/ai/deepl_with_playwright.py
@@ -1,5 +1,4 @@
from playwright.sync_api import sync_playwright
-<<<<<<< HEAD
import random
import logging
@@ -11,23 +10,25 @@ def trans_text(original_text):
try:
# Playwright 브라우저 인스턴스 생성 (헤드리스 모드)
browser = p.chromium.launch(headless=True) # 여기서 headless=False로 설정하면 GUI 모드로 실행
- page = browser.new_page()
-
- # PC 사용자 에이전트 중 하나를 랜덤하게 선택
- USER_AGENTS = [
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.0.0",
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0",
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 OPR/85.0.0.0"
- ]
- random_user_agent = random.choice(USER_AGENTS)
-
- context = browser.new_context(user_agent=random_user_agent)
+
+ # 동영상 녹화 설정을 포함하여 브라우저 컨텍스트 생성
+ context = browser.new_context(
+ user_agent=random.choice([
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.0.0",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 OPR/85.0.0.0"
+ ]),
+ # # 동영상 녹화 설정 추가
+ # record_video_dir="videos/", # 동영상이 저장될 디렉토리 지정
+ # record_video_size={"width": 1280, "height": 720} # 동영상 크기 지정
+ )
page = context.new_page()
# DeepL 웹사이트 접속
- page.goto('https://www.deepl.com/ko/translator')
+ # page.goto('https://www.deepl.com/ko/translator')
+ page.goto('https://www.deepl.com/translator#zh/ko/'+ original_text)
# JavaScript를 사용하여 편집 가능한 div에 텍스트 입력
page.evaluate("""(text) => {
@@ -42,7 +43,9 @@ def trans_text(original_text):
# "visible": 요소가 DOM에 삽입되어 있으며 렌더링된 상태(화면에 보이는 상태)임을 의미합니다. CSS를 통해 숨겨진 요소는 visible 상태에 해당하지 않습니다.
# "hidden": 요소가 DOM에 존재하지 않거나 렌더링되지 않아 화면에 보이지 않음을 의미합니다. 이는 요소가 아예 존재하지 않거나, CSS 등을 통해 숨겨진 경우에 해당합니다.
# timeout=10000 (10초 내에 해당요소가 "state" 될때까지 대기)
- page.wait_for_function('document.querySelector("[data-testid="translator-target-input"]").textContent.length > 0')
+ # page.wait_for_function('document.querySelector("[data-testid="translator-target-input"]").textContent.length > 0')
+ # page.wait_for_function('document.querySelector(\'[data-testid="translator-target-input"]\').textContent.length > 0')
+ page.wait_for_function("document.querySelector(\"[data-testid='translator-target-input']\").textContent.length > 0")
page.wait_for_selector('[data-testid="translator-target-input"]', state="visible", timeout=10000)
translated_text = page.text_content('[data-testid="translator-target-input"]')
@@ -68,10 +71,75 @@ def trans_text(original_text):
return "에러발생으로 인한 번역 실패."
finally:
- if browser: # browser가 초기화되었는지 확인
+ if context: # context가 초기화되었는지 확인하고, 종료
+ context.close()
+ if browser: # browser가 초기화되었는지 확인하고, 종료
browser.close()
logger.info("playwright Browser 닫힘.")
return translated_text
-=======
->>>>>>> 4b4ff58484a1cc6a2080061367ea02ec8d38e8b7
+
+def trans_list_text(original_texts):
+ with sync_playwright() as p:
+ browser = p.chromium.launch(headless=True) # 여기서 headless=False로 설정하면 GUI 모드로 실행
+ # 동영상 녹화 설정을 포함하여 브라우저 컨텍스트 생성
+ context = browser.new_context(
+ user_agent=random.choice([
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.0.0",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0",
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 12_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 OPR/85.0.0.0"
+ ]),
+ # # 동영상 녹화 설정 추가
+ # record_video_dir="videos/", # 동영상이 저장될 디렉토리 지정
+ # record_video_size={"width": 1280, "height": 720} # 동영상 크기 지정
+ )
+ page = context.new_page()
+ page.goto('https://www.deepl.com/translator#zh/ko/')
+
+ translated_texts = [] # 번역된 텍스트를 저장할 리스트
+
+ for text in original_texts:
+ # contenteditable 속성을 가진 div에 텍스트를 직접 설정
+ # page.evaluate("""(text) => {
+ # const editor = document.querySelector('[data-testid="translator-source-input"] div[contenteditable="true"]');
+ # editor.textContent = text;
+ # }""", text)
+
+ page.evaluate("""(text) => {
+ const editor = document.querySelector('[data-testid="translator-source-input"] div[contenteditable="true"]');
+ editor.textContent = text;
+ const inputEvent = new Event('input', { bubbles: true });
+ editor.dispatchEvent(inputEvent);
+ }""", text)
+ # 번역이 완료될 때까지 기다림
+
+ page.wait_for_function("document.querySelector(\"[data-testid='translator-target-input']\").textContent.length > 0")
+
+ page.wait_for_selector('[data-testid="translator-target-input"]', state="visible", timeout=10000)
+
+ # 번역된 텍스트 추출
+ translated_text = page.text_content('[data-testid="translator-target-input"]')
+ translated_texts.append(translated_text.strip())
+
+ browser.close()
+ return translated_texts
+
+# ttt = '''
+# 贴片款(小号) 240*300mm\n\n
+# 贴片款(中号) 440*315mm\n\n
+# 贴片款(大号) 590*440mm\n\n
+# '''
+# tttt = trans_text(ttt)
+
+
+# # test = []
+# # test.append('贴片款(小号) 240*300mm')
+# # test.append('贴片款(中号) 440*315mm')
+# # test.append('贴片款(大号) 590*440mm')
+
+# # translated_text = trans_list_text(test)
+
+
+# print(f"번역된 글자 : {ttt}")
\ No newline at end of file
diff --git a/edit/detail1.py b/edit/detail1.py
index 39ec0be..bd4c20b 100644
--- a/edit/detail1.py
+++ b/edit/detail1.py
@@ -240,6 +240,17 @@ def find_delivery_fee(weight, delv_collection):
# return product_info_text
+def original_html(current_html):
+ # BeautifulSoup 객체 생성
+ soup = BeautifulSoup(current_html, 'html.parser')
+
+ # "img class='image_resized'" 태그만 추출
+ resized_images = soup.find_all('img', class_='image_resized')
+
+ # 추출된 태그들로 새로운 HTML 문자열 생성
+ original_html_text = ''.join(str(tag) for tag in resized_images)
+
+ return original_html_text
def NS_info_with_HTML(products):
# 상품 정보를 담을 5x1 표 생성
@@ -534,16 +545,17 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
try:
# # data-value 속성 값을 가져옵니다.
current_value = textarea.get_attribute("data-value")
+ original_html_tags = original_html(current_value)
# logger.debug(f"현재 속성값 :{current_value}")
- product_info.current_value = current_value
+ product_info.current_value = original_html_tags
logger.debug("현재 속성값 수집 완료")
# # ============번역을 위한 사전작업============
# 이미지 Url 수집
# translated_image_urls = [] # 번역된 이미지 URL들을 저장할 리스트
- detail_images = fetch_image_urls(current_value)
- logger.debug(f"detail_images URLs \n {detail_images}")
+ detail_images = fetch_image_urls(original_html_tags)
+ # logger.debug(f"detail_images URLs \n {detail_images}")
product_info.detail_image_urls = detail_images
# 원본 URL을 빈문자열로 대체
@@ -554,26 +566,24 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
# # ============번역을 위한 사전작업============
logger.debug("product_info_card 결합.")
- new_value = product_info_card + cost_add_text + current_value
+ new_value = product_info_card +'
' + cost_add_text +'
' +original_html_tags
# textarea.send_keys(product_info_card)
time.sleep(0.2)
logger.debug("결합.")
# 결합된 값을 다시 textarea에 설정
- try:
- # # data-value 속성을 새로운 값으로 설정합니다.
- driver.execute_script("arguments[0].setAttribute('data-value', arguments[1]);", textarea, new_value)
-
- # # driver.execute_script("arguments[0].innerHTML = arguments[1]", textarea, new_value)
- # # driver.execute_script("arguments[0].innerHTML = arguments[1]", detail_content, new_value);
+ # # data-value 속성을 새로운 값으로 설정합니다.
+ driver.execute_script("arguments[0].setAttribute('data-value', arguments[1]);", textarea, new_value)
+
+ # # driver.execute_script("arguments[0].innerHTML = arguments[1]", textarea, new_value)
+ # # driver.execute_script("arguments[0].innerHTML = arguments[1]", detail_content, new_value);
+
+ # # JavaScript를 사용하여 textarea 값 설정
+ # script = "arguments[0].value = arguments[1];"
+ # driver.execute_script(script, textarea, new_value)
+ time.sleep(0.5)
+ logger.debug("새로운 값이 성공적으로 설정됨.")
- # # JavaScript를 사용하여 textarea 값 설정
- # script = "arguments[0].value = arguments[1];"
- # driver.execute_script(script, textarea, new_value)
- time.sleep(0.5)
- logger.debug("새로운 값이 성공적으로 설정됨.")
- except Exception as e:
- logger.error(f"새로운 값 설정 중 오류 발생: {e}", exc_info=True)
time.sleep(0.2)
# textarea.send_keys(Keys.ENTER)
@@ -626,8 +636,10 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
+ trans_img_tag = login_info["whether_modifyImageTanslation"]
+ logger.debug(f"whether_modifyImageTanslation : {trans_img_tag}")
- if login_info.whether_modifyImageTanslation:
+ if login_info["whether_modifyImageTanslation"]:
logger.debug("상세페이지 이미지 번역 시작")
try:
for i, detail_image in enumerate(detail_images):
@@ -650,9 +662,6 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
logger.debug("====번역이미지 붙여넣기 완료=====")
-
-
-
logger.debug("상세페이지 편집 저장")
click_element(driver, "XPATH", save_button_xpath, 5, 'js')
diff --git a/edit/detail1_a.py b/edit/detail_with_img_trans.py
similarity index 61%
rename from edit/detail1_a.py
rename to edit/detail_with_img_trans.py
index ff1d9f0..7ad5433 100644
--- a/edit/detail1_a.py
+++ b/edit/detail_with_img_trans.py
@@ -10,7 +10,7 @@ import sys, re
import numpy as np
from naver_search import parse_naver_shopping
from edit.naver_code import find_naver_code
-from edit.action_elements import click_element, return_element
+from edit.action_elements import click_element, return_element, click_and_confirm_tab
from img_trans.image_trans import image_trans
import logging
from bs4 import BeautifulSoup
@@ -22,6 +22,7 @@ logger = logging.getLogger('default_logger')
avg_price = 0
+
def paste_image_in_editor(driver, editor_element):
action = ActionChains(driver)
action.click(editor_element) # 에디터를 클릭하여 포커스를 맞춥니다.
@@ -72,27 +73,25 @@ def fetch_image_urls(html_content):
return image_urls
-def safe_generate_content(gemini, image_src, product_title, max_retries=3, initial_wait=1):
+def safe_generate_content(gemini, product_info, max_retries=3, initial_wait=1):
retry_count = 0
wait_time = initial_wait
while retry_count < max_retries:
try:
- return gemini.generate_description(image_src, product_title)
+ return gemini.generate_description(product_info)
# except InternalServerError as e:
# logger.debug(f"Retry {retry_count + 1}/{max_retries} for InternalServerError")
# time.sleep(wait_time)
# wait_time *= 2 # Exponential backoff
# retry_count += 1
except Exception as e:
+ logger.debug(f"예외 발생 : {e}", exc_info=True)
logger.debug(f"예외 발생으로 재시도 : {retry_count + 1}/{max_retries}")
time.sleep(wait_time)
wait_time *= 2 # Exponential backoff
retry_count += 1
- # Final attempt without catching the exception
- return gemini.generate_content(image_src, product_title)
-
def selling_price(tao_bao_price, shipping_fee=6500, target_margin_rate=0.29, market_fee_rate=0.13,
card_fee_rate=0.035, exchange_rate=200):
"""
@@ -186,65 +185,76 @@ def find_delivery_fee(weight, delv_collection):
return fees[closest_weight_index]
#네이버쇼핑 함수
-def NS_info(products):
- # 각 상품 정보에 접근하여 텍스트로 가공
- product_info_text = ""
- global avg_price
- avg_price = 0
- prices = []
+# def NS_info(products):
+# # 각 상품 정보에 접근하여 텍스트로 가공
+# product_info_text = ""
+# global avg_price
+# avg_price = 0
+# prices = []
- for index, product in enumerate(products):
- idx = index + 1
- product_info_text += '
\n' # 카드 시작 태그
- product_info_text += f"=================={idx} 번째 네이버 상품========================"
- # 이미지 태그
- product_info_text += f'

\n'
+# for index, product in enumerate(products):
+# idx = index + 1
+# product_info_text += '
\n' # 카드 시작 태그
+# product_info_text += f"=================={idx} 번째 네이버 상품========================"
+# # 이미지 태그
+# product_info_text += f'

\n'
- # 상품 세부 정보 태그 시작
- product_info_text += '
\n'
+# # 상품 세부 정보 태그 시작
+# product_info_text += '
\n'
- # 상품명 태그
- # product_info_text += f'
상품명 : {product["productTitle"]}
\n'
- product_info_text += f'
상품명 : {product["productTitle"]}
\n'
- # 가격 태그
- # 상품 가격을 숫자로 변환하고 포맷
- if isinstance(product["price"], str):
- # 문자열인 경우 숫자로 변환
- price = int(product["price"].replace(",", "")) # 쉼표 제거 후 정수 변환
- else:
- price = product["price"] # 이미 숫자인 경우 변환 없음
+# # 상품명 태그
+# # product_info_text += f'
상품명 : {product["productTitle"]}
\n'
+# product_info_text += f'
상품명 : {product["productTitle"]}
\n'
+# # 가격 태그
+# # 상품 가격을 숫자로 변환하고 포맷
+# if isinstance(product["price"], str):
+# # 문자열인 경우 숫자로 변환
+# price = int(product["price"].replace(",", "")) # 쉼표 제거 후 정수 변환
+# else:
+# price = product["price"] # 이미 숫자인 경우 변환 없음
- prices.append(price)
- formatted_price = format(price, ",") + "원" # 천 단위 구분으로 포맷
- product_info_text += f'
가격: {formatted_price}
'
+# prices.append(price)
+# formatted_price = format(price, ",") + "원" # 천 단위 구분으로 포맷
+# product_info_text += f'
가격: {formatted_price}
'
- # 순위 태그
- product_info_text += f'
순위: {product["rank"]}
\n'
+# # 순위 태그
+# product_info_text += f'
순위: {product["rank"]}
\n'
- product_info_text += "=================================================================="
+# product_info_text += "=================================================================="
- # 상품 세부 정보 태그 종료
- product_info_text += '
\n'
+# # 상품 세부 정보 태그 종료
+# product_info_text += '
\n'
- product_info_text += '
\n' # 카드 종료 태그
- avg_price += int(product["price"])
+# product_info_text += '
\n' # 카드 종료 태그
+# avg_price += int(product["price"])
- # avg_price = round(avg_price/len(products),0)
+# # avg_price = round(avg_price/len(products),0)
- if products: # products가 비어 있지 않은 경우에만 평균 가격 계산
- avg_price = round(avg_price / len(products), 0)
- low_price = min(prices)
- high_price = max(prices)
- product_info_text += f'네이버 상품의 최저 가격은 [{low_price}]'
- product_info_text += f'네이버 상품의 평균 가격은 [{avg_price}]'
- product_info_text += f'네이버 상품의 최고 가격은 [{high_price}]'
+# if products: # products가 비어 있지 않은 경우에만 평균 가격 계산
+# avg_price = round(avg_price / len(products), 0)
+# low_price = min(prices)
+# high_price = max(prices)
+# product_info_text += f'네이버 상품의 최저 가격은 [{low_price}]'
+# product_info_text += f'네이버 상품의 평균 가격은 [{avg_price}]'
+# product_info_text += f'네이버 상품의 최고 가격은 [{high_price}]'
- return product_info_text
+# return product_info_text
+def original_html(current_html):
+ # BeautifulSoup 객체 생성
+ soup = BeautifulSoup(current_html, 'html.parser')
+
+ # "img class='image_resized'" 태그만 추출
+ resized_images = soup.find_all('img', class_='image_resized')
+
+ # 추출된 태그들로 새로운 HTML 문자열 생성
+ original_html_text = ''.join(str(tag) for tag in resized_images)
+
+ return original_html_text
def NS_info_with_HTML(products):
# 상품 정보를 담을 5x1 표 생성
- product_info_text = ""
+ product_info_table = ""
global avg_price
avg_price = 0
@@ -257,44 +267,18 @@ def NS_info_with_HTML(products):
# 각 상품 카드를 생성하고 테이블의 셀로 추가
product_card = create_product_card(product["productTitle"], product["imageUrl"], formatted_price, product["rank"], product["purchase"], product["review"])
- product_info_text += f"| {product_card} | "
+ product_info_table += f"{product_card} | "
avg_price += price
- product_info_text += "
"
+ product_info_table += "
"
if products:
avg_price = round(avg_price / len(products), 0)
- product_info_text += f'네이버 상품의 평균 가격은 {avg_price:,.0f}원입니다.
'
+ product_info_table += f'네이버 상품의 평균 가격은 {avg_price:,.0f}원입니다.
'
- return product_info_text
+ return product_info_table
-#네이버쇼핑 함수 HTML
-def NS_info_with_HTML_ori(products):
- product_info_text = ""
- global avg_price
- avg_price = 0
-
- for product in products:
- if isinstance(product["price"], str):
- price = int(product["price"].replace(",", ""))
- else:
- price = product["price"]
- formatted_price = format(price, ",") + "원"
-
- # 각 상품 카드를 생성하여 테이블의 셀로 추가
- product_card = create_product_card(product["productTitle"], product["imageUrl"], formatted_price, product["rank"])
- product_info_text += f"{product_card} | "
- avg_price += price
-
- product_info_text += ""
-
- if products:
- avg_price = round(avg_price / len(products), 0)
- product_info_text += f'네이버 상품의 평균 가격은 {avg_price}원입니다.
'
-
- return product_info_text
-
def naver_prices(products):
prices = []
for product in products:
@@ -337,64 +321,51 @@ def create_product_card(product_name, image_url, price, rank, purchase, review):
return product_card
-def create_product_card_ori(product_name, image_url, price, rank):
- # 이미지 크기를 직접 지정
- html_text = f"""
-
-
-  |
- 가격: {price} |
-
-
- | 순위: {rank} |
-
-
- |
-
-
- | {product_name} |
-
-
- """
- return html_text
+# #네이버쇼핑 함수 마크다운
+# def NS_info_markdown(products):
+# product_info_md = ""
+# global avg_price
+# avg_price = 0
-
-#네이버쇼핑 함수 마크다운
-def NS_info_markdown(products):
- product_info_md = ""
- global avg_price
- avg_price = 0
-
- for index, product in enumerate(products):
- idx = index + 1
- # 제품명을 헤더로 표시
- product_info_md += f"### {idx}번상품. {product['productTitle']}\n"
+# for index, product in enumerate(products):
+# idx = index + 1
+# # 제품명을 헤더로 표시
+# product_info_md += f"### {idx}번상품. {product['productTitle']}\n"
- # 이미지 추가
- product_info_md += f"\n\n"
+# # 이미지 추가
+# product_info_md += f"\n\n"
- # 가격과 순위 정보
- if isinstance(product["price"], str):
- price = int(product["price"].replace(",", "")) # 쉼표 제거 후 정수 변환
- else:
- price = product["price"]
- formatted_price = format(price, ",") + "원"
+# # 가격과 순위 정보
+# if isinstance(product["price"], str):
+# price = int(product["price"].replace(",", "")) # 쉼표 제거 후 정수 변환
+# else:
+# price = product["price"]
+# formatted_price = format(price, ",") + "원"
- product_info_md += f"- **가격:** {formatted_price}\n"
- product_info_md += f"- **순위:** {product['rank']}\n\n"
+# product_info_md += f"- **가격:** {formatted_price}\n"
+# product_info_md += f"- **순위:** {product['rank']}\n\n"
- avg_price += price # 평균 가격 계산을 위해 가격 추가
+# avg_price += price # 평균 가격 계산을 위해 가격 추가
- if products: # products가 비어 있지 않은 경우에만 평균 가격 계산
- avg_price = round(avg_price / len(products), 0)
- product_info_md += f"**네이버 상품의 평균 가격은 {avg_price}원입니다.**\n"
+# if products: # products가 비어 있지 않은 경우에만 평균 가격 계산
+# avg_price = round(avg_price / len(products), 0)
+# product_info_md += f"**네이버 상품의 평균 가격은 {avg_price}원입니다.**\n"
- return product_info_md
+# return product_info_md
-def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver_codes):
- product_title = product_info.init_title
- product_low_cost = product_info.tao_low_price
- product_high_cost = product_info.tao_high_price
+def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver_codes, login_info):
+
+ detail_css = ".ant-tabs-tab:nth-child(6)"
+
+ thumb_data_note = "5"
+ click_and_confirm_tab(driver, thumb_data_note, 10)
+
+
+ product_keyword = product_info.keyword_title
+ # product_low_cost = product_info.tao_low_price
+ # product_high_cost = product_info.tao_high_price
+ product_low_cost = product_info.option_low_price
+ product_high_cost = product_info.option_high_price
image_src = product_info.main_image_url
try:
@@ -409,6 +380,30 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
logger.debug(f"카테고리 코드 검색 중 예외 발생 : {e}", exc_info=True)
naver_code = ""
+
+
+ try:
+ logger.debug("네이버쇼핑 파싱 중")
+ products = parse_naver_shopping(product_keyword, naver_code, isOverseas=1, sortcount=5)
+ logger.debug("네이버쇼핑 파싱 완료")
+ # logger.debug(f"네이버 파싱된 상품 리스트 \n {products}")
+ product_info.naver_products = products
+
+ # 네이버 상품가격 담기
+ naver_price = naver_prices(products)
+ product_info.naver_low_price = naver_price[0]
+ product_info.naver_avg_price = naver_price[1]
+ product_info.naver_high_price = naver_price[2]
+
+ # product_info_text = NS_info(products)
+ product_info_card = NS_info_with_HTML(products)
+ # logger.debug(f"수집된 정보 \n {product_info_card} \n")
+ logger.debug("네이버쇼핑 파싱 완료")
+ except Exception as e:
+ logger.debug(f"네이버쇼핑 파싱 중 에러발생 : {e}", exc_info=True)
+
+
+
# 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')
# testt = find_delivery_fee(7,delv_collection)
@@ -430,8 +425,8 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
except Exception as e:
logger.debug(f"상세페이지 탭으로 이동 중 오류 발생: 요소를 찾을 수 없습니다. : {e}", exc_info=True)
# detail_tab = driver.find_element(By.CSS_SELECTOR, ".ant-tabs-tab:nth-child(6)")
- detail_tab.click()
- time.sleep(2) # 페이지 로딩 대기
+ # detail_tab.click()
+ time.sleep(0.2) # 페이지 로딩 대기
# 상세페이지 내용 수정
try:
@@ -446,11 +441,10 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
try:
ActionChains(driver).move_to_element(detail_content).click().perform()
time.sleep(1)
-
logger.debug("AI 이미지 처리중")
# contents = bard_img(image_src)
# contents = gemini.generate_description(image_src, product_title)
- aicontents = safe_generate_content(gemini, image_src, product_title)
+ aicontents = safe_generate_content(gemini, product_info)
logger.debug(f"{aicontents}")
product_info.ai_contents = aicontents
logger.debug("AI 이미지 처리 완료")
@@ -467,30 +461,54 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
logger.debug(f"추가포장비 추정 : {packing_fee}")
product_info.packing_fee = packing_fee
- logger.debug("네이버쇼핑 파싱 중")
- products = parse_naver_shopping(product_title, naver_code, isOverseas=1, sortcount=5)
-
- logger.debug(f"네이버 파싱된 상품 리스트 \n {products}")
- product_info.naver_products = products
-
- # 네이버 상품가격 담기
- naver_price = naver_prices(products)
- product_info.naver_low_price = naver_price[0]
- product_info.naver_avg_price = naver_price[1]
- product_info.naver_high_price = naver_price[2]
-
- # product_info_text = NS_info(products)
- product_info_text = NS_info_with_HTML(products)
- # logger.debug(f"수집된 정보 \n {product_info_text} \n")
- logger.debug("네이버쇼핑 파싱 완료")
except Exception as e:
logger.debug(f"상세페이지 편집 중 에러발생 : {e}", exc_info=True)
+
try:
+ # 가격 정보 계산
+ low_cost, low_margin = selling_price(product_low_cost, delv_fee, 0.29)
+ high_cost, high_margin = selling_price(product_high_cost, delv_fee, 0.29)
+ low_delv_fee = avg_price - low_cost
+ high_delv_fee = avg_price - high_cost
+
+ # 마진율 계산
+ low_margin_r = round((low_margin / low_cost) * 100, 2)
+ high_margin_r = round((high_margin / high_cost) * 100, 2)
+
+ # 텍스트 조합
+ cost_add_text = f"""
+ ==== 가격과 마진율 ====
+ 해당 제품의 네이버 평균가격은 {avg_price:,.0f}원입니다.
+ 해당 제품의 무게배송비는 {delv_fee:,.0f}원입니다.
+
+ **마진율 확보를 위한 판매가 범위:** {low_cost:,.0f}원 ~ {high_cost:,.0f}원
+
+ **저가 중심 계산:**
+ * 무게 배송비 대비: {low_delv_fee:,.0f}원 {('낮은' if low_delv_fee < 0 else '높은')} 편
+ * 마진율: {low_margin_r:,.2f}%
+ **고가중심 계산:**
+ * 무게 배송비 대비: {high_delv_fee:,.0f}원 {('낮은' if high_delv_fee < 0 else '높은')} 편
+ * 마진율: {high_margin_r:,.2f}%
+
+ **추가 정보:**
+ * 해당 제품의 파손 여부 및 무게 오차를 고려하여 더하기 마진을 설정하세요.
+ =======================================
+ """
+
+ # time.sleep(2)
+ # detail_content.send_keys(cost_add_text)
+
+ except Exception as e:
+ logger.debug(f"가격정보 생성 중 에러 : {e}", exc_info=True)
+
+
+ try:
+ logger.debug("HTML 수정 버튼 클릭 .")
html_btn_by_contains_xpath="//button[contains(.,'소스')]"
html_btn_css = "ck.ck-button.ck-source-editing-button.ck-off.ck-button_with-text"
html_btn_xpath="//div[@id='productMainContentContainerId']/div/div/div[2]/div[2]/div/div/div[2]/div/div/button[8]"
- click_element(driver, 'XPATH', html_btn_xpath, 5, 'js')
+ click_element(driver, 'XPATH', html_btn_xpath, 5, 'ac')
# 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)
@@ -498,7 +516,6 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
# )
# logger.debug("HTML 수정 버튼을 성공적으로 찾았습니다.")
# html_btn.click()
- logger.debug("HTML 수정 버튼 클릭 .")
except Exception as e:
logger.debug(f"HTML 수정 버튼 요소를 찾을 수 없습니다. : {e}", exc_info=True)
@@ -507,62 +524,78 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
try:
+ # textarea_css = "ck-source-editing-area"
+ # click_element(driver, 'CSS_SELECTOR', textarea_css, 10, 'js')
textarea = WebDriverWait(driver, 5).until(
EC.presence_of_element_located((By.CLASS_NAME, "ck-source-editing-area"))
)
logger.debug("textarea버튼을 성공적으로 찾았습니다.")
- sys.stdout.flush()
- textarea.click()
+ time.sleep(0.2)
+ actions = ActionChains(driver)
+ actions.move_to_element(textarea).perform() # 요소로 스크롤
+ logger.debug("'textarea' 요소로 스크롤 실행")
+ time.sleep(0.2)
+ actions.click(textarea).perform()
+ logger.debug("'textarea' 요소 클릭 실행")
+
+ # textarea.click()
except Exception as e:
logger.debug(f"textarea버튼 요소를 찾을 수 없습니다. : {e}", exc_info=True)
try:
# # data-value 속성 값을 가져옵니다.
current_value = textarea.get_attribute("data-value")
+ original_html_tags = original_html(current_value)
# logger.debug(f"현재 속성값 :{current_value}")
- product_info.current_value = current_value
+ product_info.current_value = original_html_tags
logger.debug("현재 속성값 수집 완료")
+ # # ============번역을 위한 사전작업============
# 이미지 Url 수집
# translated_image_urls = [] # 번역된 이미지 URL들을 저장할 리스트
- detail_images = fetch_image_urls(current_value)
- logger.debug(f"detail_images URLs \n {detail_images}")
+ detail_images = fetch_image_urls(original_html_tags)
+ # logger.debug(f"detail_images URLs \n {detail_images}")
product_info.detail_image_urls = detail_images
-
# 원본 URL을 빈문자열로 대체
- logger.debug("원본 URL을 빈 문자열로 대체")
- for original_url in detail_images:
- current_value = current_value.replace(original_url, "")
+ # logger.debug("원본 URL을 빈 문자열로 대체")
+ # for original_url in detail_images:
+ # current_value = current_value.replace(original_url, "")
+ # logger.debug("새로운 data-value 값으로 설정되었습니다.")
+ # # ============번역을 위한 사전작업============
-
- # # # 새로운 data-value 값을 생성합니다.
- # new_value = product_info_text + "\n" + current_value
- # # logger.debug(f"new_value \n {new_value}")
- # product_info.new_value = new_value
- # logger.debug("새로운 data-value 값 생성")
-
- # # # data-value 속성을 새로운 값으로 설정합니다.
- # 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(1)
- # # driver.execute_script("arguments[0].innerHTML = arguments[1]", detail_content, new_value);
-
- logger.debug("새로운 data-value 값으로 설정되었습니다.")
-
- # save_button.click()
- click_element(driver, 'XPATH', save_button_xpath, 5, 'js')
+ logger.debug("product_info_card 결합.")
+ new_value = product_info_card +'
' + cost_add_text +'
' +original_html_tags
+ # textarea.send_keys(product_info_card)
time.sleep(0.2)
+ logger.debug("결합.")
+ # 결합된 값을 다시 textarea에 설정
+ try:
+ # # data-value 속성을 새로운 값으로 설정합니다.
+ driver.execute_script("arguments[0].setAttribute('data-value', arguments[1]);", textarea, new_value)
+
+ # # driver.execute_script("arguments[0].innerHTML = arguments[1]", textarea, new_value)
+ # # driver.execute_script("arguments[0].innerHTML = arguments[1]", detail_content, new_value);
- # textarea.send_keys(product_info_text)
- # logger.debug("detail_content 전송.")
+ # # JavaScript를 사용하여 textarea 값 설정
+ # script = "arguments[0].value = arguments[1];"
+ # driver.execute_script(script, textarea, new_value)
+ time.sleep(0.5)
+ logger.debug("새로운 값이 성공적으로 설정됨.")
+ except Exception as e:
+ logger.error(f"새로운 값 설정 중 오류 발생: {e}", exc_info=True)
+ time.sleep(0.2)
+ # textarea.send_keys(Keys.ENTER)
# textarea.send_keys(Keys.ENTER)
# logger.debug("엔터키 전송.")
+ click_element(driver, 'XPATH', save_button_xpath, 5, 'js')
+ time.sleep(0.2)
+ logger.debug("저장버튼 전송.")
+
# html_btn.click()
click_element(driver, 'XPATH', html_btn_xpath, 5, 'js')
@@ -588,13 +621,15 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
# contents 변수의 값이 None이 아닐 때만 send_keys 메서드를 호출합니다.
if aicontents is not None:
detail_content.send_keys(aicontents)
+ logger.debug(f"AI 컨텐츠 입력완료")
+
else:
# contents 변수가 None일 때의 대체 처리
# 예: detail_content.send_keys("") 또는 아무 동작도 수행하지 않음
pass
-
+
time.sleep(0.5)
-
+
detail_content.send_keys(Keys.ENTER)
detail_content.send_keys(Keys.ENTER)
detail_content.send_keys(Keys.ENTER)
@@ -602,94 +637,34 @@ def modify_detail_page(driver, product_info, gemini, delv_collection, json_naver
logger.error(f"AI 컨텐츠 입력 중 에러발생 : {e}", exc_info=True)
- logger.debug("상세페이지 이미지 번역 시작")
- 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("이미지 번역 완료")
- except Exception as e:
- logger.error(f"이미지 번역 중 에러발생 : {e}", exc_info=True)
-
-
- logger.debug("====번역이미지 붙여넣기 완료=====")
-
- # 인용버튼 클릭
- # quote_button = driver.find_element(By.XPATH, "//div[@id='productMainContentContainerId']/div/div/div[2]/div[2]/div/div/div[2]/div/div/button[6]")
- # quote_button = driver.find_element(By.CSS_SELECTOR, ".ck:nth-child(16)")
-
- # try:
- # quote_button = WebDriverWait(driver, 10).until(
- # EC.presence_of_element_located((By.CSS_SELECTOR, ".ck:nth-child(16)"))
- # )
- # logger.debug("인용버튼을 성공적으로 찾았습니다.")
- # except:
- # logger.debug("인용버튼 요소를 찾을 수 없습니다.")
- # quote_button.click()
- # time.sleep(0.5)
+ if login_info.whether_modifyImageTanslation:
+ logger.debug("상세페이지 이미지 번역 시작")
+ 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("이미지 번역 완료")
+ except Exception as e:
+ logger.error(f"이미지 번역 중 에러발생 : {e}", exc_info=True)
- try:
- # 가격 정보 계산
- low_cost, low_margin = selling_price(product_low_cost, delv_fee, 0.29)
- high_cost, high_margin = selling_price(product_high_cost, delv_fee, 0.29)
- low_delv_fee = avg_price - low_cost
- high_delv_fee = avg_price - high_cost
-
- # 마진율 계산
- low_margin_r = round((low_margin / low_cost) * 100, 2)
- high_margin_r = round((high_margin / high_cost) * 100, 2)
-
- # 텍스트 조합
- add_text = f"""
- ============= 가격과 마진율 =============
- 해당 제품의 네이버 평균가격은 {avg_price:,.0f}원입니다.
- 해당 제품의 무게배송비는 {delv_fee:,.0f}원입니다.
-
- **마진율 확보를 위한 판매가 범위:** {low_cost:,.0f}원 ~ {high_cost:,.0f}원
-
- **저가:**
- * 무게 배송비 대비: {low_delv_fee:,.0f}원 {('낮은' if low_delv_fee < 0 else '높은')} 편
- * 마진율: {low_margin_r:,.2f}%
-
- **고가:**
- * 무게 배송비 대비: {high_delv_fee:,.0f}원 {('낮은' if high_delv_fee < 0 else '높은')} 편
- * 마진율: {high_margin_r:,.2f}%
-
- **적정 배송비:** {low_delv_fee:,.0f}원 ~ {high_delv_fee:,.0f}원
-
- **추가 정보:**
- * 해당 제품의 파손 여부 및 무게 오차를 고려하여 더하기 마진을 설정하세요.
- =======================================
- """
-
- detail_content.send_keys(add_text)
- time.sleep(2)
- except Exception as e:
- logger.debug(f"가격정보 생성 중 에러 : {e}", exc_info=True)
-
- # 저장 버튼 클릭
- # 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}", exc_info=True)
- # save_button = driver.find_element(By.XPATH, "//button[contains(.,'저장하기')]")
- # save_button.click()
+ logger.debug("====번역이미지 붙여넣기 완료=====")
+
+
+
+
logger.debug("상세페이지 편집 저장")
click_element(driver, "XPATH", save_button_xpath, 5, 'js')
diff --git a/edit/ns.py b/edit/ns.py
new file mode 100644
index 0000000..6774185
--- /dev/null
+++ b/edit/ns.py
@@ -0,0 +1,188 @@
+from playwright.sync_api import sync_playwright
+from bs4 import BeautifulSoup
+import requests, json
+
+def run(playwright, keyword):
+ browser = playwright.chromium.launch(headless=False) # 헤드리스 모드 비활성화
+ context = browser.new_context(
+ user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36",
+ locale="en-US", # 언어 설정
+ timezone_id="America/New_York" # 시간대 설정
+ )
+ page = context.new_page()
+
+ # navigator.webdriver 비활성화
+ page.evaluate("navigator.webdriver = undefined")
+
+ print("브라우저 열기 및 사용자 에이전트 설정 완료")
+
+ page.goto(f"https://search.shopping.naver.com/search/all?query={keyword}&bt=-1&frm=NVSCPRO")
+ print("페이지 로딩 완료")
+
+ # 접근 시간 지연
+ page.wait_for_timeout(1000)
+
+ print("페이지 로딩 완료")
+ # 페이지의 HTML 가져오기
+ html = page.content()
+ print(html)
+
+ soup = BeautifulSoup(html, 'html.parser')
+
+ products = extract_product_info(soup)
+
+ for product in products:
+ print(product.text)
+
+ browser.close()
+
+
+def extract_product_info(soup):
+ # 상품 정보를 담을 리스트 초기화
+ product_info_list = []
+
+ # 각 상품에 대한 정보 추출
+ products = soup.find_all('div', class_='basicList_info_area__17Xyo')
+ print(f"products : {products}")
+ for i, product in enumerate(products, 1):
+ # 상품명
+ title = product.find('a', class_='product_link__TrAac').get('title')
+ print(f"{i}번째 상품 title : {title}")
+
+ # 썸네일 URL
+ thumbnail_element = product.find('a', class_='thumbnail_thumb__Bxb6Z')
+ thumbnail_url = thumbnail_element.find('img').get('src') if thumbnail_element else None
+ print(f"{i}번째 상품 thumbnail_url : {thumbnail_url}")
+
+ # 가격과 배송비
+ price_area = product.find('div', class_='product_price_area__eTg7I')
+ price = price_area.find('span', class_='price_num__S2p_v').text.strip() if price_area else None
+ print(f"{i}번째 상품 price : {price}")
+ delivery_fee = price_area.find('span', class_='price_delivery__yw_We').text.strip() if price_area else None
+ print(f"{i}번째 상품 delivery_fee : {delivery_fee}")
+
+ # 카테고리
+ categories = [cat.text for cat in product.find_all('span', class_='product_category__l4FWz')]
+ print(f"{i}번째 상품 categories : {categories}")
+
+ # 리뷰, 구매건수, 등록일, 찜하기
+ etc_info = product.find('div', class_='product_etc_box__ElfVA')
+ review_count = etc_info.find('a', text='리뷰').find('em').text if etc_info and etc_info.find('a', text='리뷰') else '0'
+ print(f"{i}번째 상품 review_count : {review_count}")
+ purchase_count = etc_info.find('span', text='구매건수').find('em').text if etc_info and etc_info.find('span', text='구매건수') else '0'
+ print(f"{i}번째 상품 purchase_count : {purchase_count}")
+ registration_date = etc_info.find('span', text='등록일').text.replace('등록일 ', '') if etc_info and etc_info.find('span', text='등록일') else None
+ print(f"{i}번째 상품 registration_date : {registration_date}")
+ zzim_count = etc_info.find('a', class_='product_btn_zzim__MQ17u').find('em').text if etc_info and etc_info.find('a', class_='product_btn_zzim__MQ17u') else '0'
+ print(f"{i}번째 상품 zzim_count : {zzim_count}")
+
+ # 사전에 정보 저장
+ product_info = {
+ 'title': title,
+ 'thumbnail_url': thumbnail_url,
+ 'price': price,
+ 'delivery_fee': delivery_fee,
+ 'categories': categories,
+ 'review_count': review_count,
+ 'purchase_count': purchase_count,
+ 'registration_date': registration_date,
+ 'zzim_count': zzim_count
+ }
+
+ product_info_list.append(product_info)
+ print(f"{i}번째 상품 정보 추가 완료")
+
+ return product_info_list
+
+
+
+def ns(keyword):
+ # 네이버 쇼핑 URL 설정
+ urlBase = "https://search.shopping.naver.com/search/all?query="
+ # urlEnd = f"&cat_id={naver_code}&frm=NVSHATC&pagingIndex=1&pagingSize=40&&productSet=overseas&sort=rel×tamp=&viewType=list"
+ urlEnd = "&frm=NVSHATC&pagingIndex=1&pagingSize=40&&productSet=overseas&sort=rel×tamp=&viewType=list"
+ url = urlBase + keyword + urlEnd
+ # print(f"네이버 카테코드는 [{naver_code}] 입니다.")
+ print("네이버 카테코드는 [생략]] 입니다.")
+ print(f"대상키워드는 [{keyword}] 입니다.")
+ headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36",
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
+ "Accept-Language": "en-US,en;q=0.9",
+ "Accept-Encoding": "gzip, deflate, br",
+ "DNT": "1", # Do Not Track 요청 헤더 (사용자의 추적을 거부)
+ "Connection": "keep-alive",
+ "Upgrade-Insecure-Requests": "1", # https로의 업그레이드를 요청
+ "Cache-Control": "max-age=0", # 캐시된 콘텐츠를 재사용하지 않도록 요청
+ }
+
+ # # 네이버 쇼핑에 접속하여 HTML 받아오기
+ # response = requests.get(url, headers=headers)
+ # soup = BeautifulSoup(response.text, 'html.parser')
+
+ # 네이버 쇼핑에 접속하여 HTML 받아오기
+ try:
+ response = requests.get(url, headers=headers)
+ html = response.text
+ print(f"response : {response}")
+ # print(f"html : {html}")
+ response.raise_for_status() # 만약 요청이 실패하면 예외 발생
+ soup = BeautifulSoup(response.text, 'html.parser')
+ next_data_str = soup.find("script", {"id": "__NEXT_DATA__"}).string
+ next_data_json = json.loads(next_data_str)
+ products_list = next_data_json["props"]["pageProps"]["initialState"]["products"]["list"]
+ products_info = []
+ for product in products_list:
+ price = product.get("item", {}).get("price")
+ productTitle = product.get("item", {}).get("productTitle")
+ category1Name = product.get("item", {}).get("category1Name")
+ category2Name = product.get("item", {}).get("category2Name")
+ category3Name = product.get("item", {}).get("category3Name")
+ category4Name = product.get("item", {}).get("category4Name")
+ openDate = product.get("item", {}).get("openDate")
+ mallCount = product.get("item", {}).get("mallCount")
+ keepCnt = product.get("item", {}).get("keepCnt")
+ overseaTp = product.get("item", {}).get("overseaTp")
+ reviewCount = product.get("item", {}).get("reviewCount")
+ reviewCountSum = product.get("item", {}).get("reviewCountSum")
+ scoreInfo = product.get("item", {}).get("scoreInfo")
+ naverPayAdAccumulatedDisplayValue = product.get("item", {}).get("naverPayAdAccumulatedDisplayValue")
+ mobileLowPrice = product.get("item", {}).get("mobileLowPrice")
+ lowPrice = product.get("item", {}).get("lowPrice")
+ deliveryFeeContent = product.get("item", {}).get("deliveryFeeContent")
+ dlvryLowPrice = product.get("item", {}).get("dlvryLowPrice")
+ imageUrl = product.get("item", {}).get("imageUrl")
+ imgSz = product.get("item", {}).get("imgSz")
+ searchKeyword = product.get("item", {}).get("searchKeyword")
+ mallProductUrl = product.get("item", {}).get("mallProductUrl")
+ mallPcUrl = product.get("item", {}).get("mallPcUrl")
+ mallName = product.get("item", {}).get("mallName")
+ manuTag = product.get("item", {}).get("manuTag")
+ #mallInfoCache = product.get("item", {}).get("mallInfoCache")
+ purchaseCnt = product.get("item", {}).get("purchaseCnt")
+ rank = product.get("item", {}).get("rank")
+
+ # 상품 정보를 딕셔너리로 만들어 리스트에 추가
+ product_info = {
+ "productTitle": productTitle,
+ "price": price,
+ "imageUrl": imageUrl,
+ "rank": rank,
+ "purchase" : purchaseCnt,
+ "review" : reviewCountSum
+ }
+ products_info.append(product_info)
+
+ print(f"키워드 검색 결과 상품 [{keyword}]에 대한 [{len(products_info)}]개의 상품정보수집 완료")
+
+ print(f"products_info \n {products_info}")
+ except Exception as e:
+ print(f"Exception : {e}")
+
+
+keywrod = "방폭등"
+
+ns(keywrod)
+
+# with sync_playwright() as playwright:
+# run(playwright, keywrod)
\ No newline at end of file
diff --git a/edit/options.py b/edit/options.py
index 405ae13..01ddea5 100644
--- a/edit/options.py
+++ b/edit/options.py
@@ -6,7 +6,7 @@ from selenium.webdriver.common.keys import Keys
import time
from edit.action_elements import click_element, return_element, click_and_confirm_tab
from ai.deepl import trans
-from ai.deepl_with_playwright import trans_text
+from ai.deepl_with_playwright import trans_text, trans_list_text
# from ai.compare import find_most_similar_image_by_one
import re
import logging
@@ -251,31 +251,35 @@ def option_name_trans(driver, product_info, option_type_number, option_count, al
ori_optionName_element = driver.find_element(By.XPATH, ori_optionName_xpath)
ori_optionName = ori_optionName_element.text.strip()
-
- ori_optionNames.append(ori_optionName)
+ cleaned_ori_optionName = replace_or_remove_special_chars(ori_optionName, allowed_special_chars, special_char_replacements)
+ ori_optionNames.append(cleaned_ori_optionName)
except Exception as e:
logger.debug(f"원본옵션명 처리중 에러발생 : {e}", exc_info=True)
# 원본 옵션명을 하나의 텍스트로 합치기
- combined_ori_optionNames = '\n\n'.join(ori_optionNames)
+ # combined_ori_optionNames = '\n\n'.join(ori_optionNames)
- logger.debug("원본 텍스트의 특수문자 제거 및 대체")
- cleaned_ori_text = replace_or_remove_special_chars(combined_ori_optionNames, allowed_special_chars, special_char_replacements)
-
- logger.debug(f"원본옵션명 집합 \n {cleaned_ori_text}")
+ # logger.debug("원본 텍스트의 특수문자 제거 및 대체")
+ # cleaned_ori_text = replace_or_remove_special_chars(combined_ori_optionNames, allowed_special_chars, special_char_replacements)
+ # logger.debug(f"원본옵션명 집합 \n {cleaned_ori_text}")
logger.debug("번역 시행")
- # trans_optionNames_text = trans_text(cleaned_ori_text) # DeepL 번역 함수
- trans_optionNames_text = trans(cleaned_ori_text) # DeepL 번역 함수
+ deepl_trans_optionNames = trans_list_text(ori_optionNames) # DeepL 번역 함수
+ # trans_optionNames_text = trans_text(cleaned_ori_text) # DeepL_with_playwright 번역 함수
- logger.debug(f"번역된 텍스트 \n {trans_optionNames_text} ")
+ # trans_optionNames_text = trans(cleaned_ori_text) # DeepL 번역 함수
+
+ logger.debug(f"번역된 텍스트 \n {deepl_trans_optionNames} ")
logger.debug("번역 텍스트의 특수문자 제거 및 대체")
- cleaned_ori_text = replace_or_remove_special_chars(trans_optionNames_text, allowed_special_chars, special_char_replacements)
-
- trans_optionNames = trans_optionNames_text.split('\n\n')
- logger.debug("번역 텍스트 나누기")
+ trans_optionNames = []
+ for deepl_trans_optionName in deepl_trans_optionNames:
+ cleand_trans_optionName = replace_or_remove_special_chars(deepl_trans_optionName, allowed_special_chars, special_char_replacements)
+ trans_optionNames.append(cleand_trans_optionName)
+
+ # trans_optionNames = trans_optionNames_text.split('\n\n')
+ # logger.debug("번역 텍스트 나누기")
logger.debug("product_info 옵션명 업데이트")
try:
diff --git a/edit/price.py b/edit/price.py
index 37d2c04..0ac74bd 100644
--- a/edit/price.py
+++ b/edit/price.py
@@ -20,116 +20,137 @@ def modify_price_page(driver, product_infos):
# 가격 탭으로 이동
logger.debug("가격탭으로 이동")
- option_tab_XPATH = "//div[@id='rc-tabs-0-tab-3']"
- keyword_tab_CSS = ".ant-tabs-tab:nth-child(3)"
- click_element(driver, 'CSS_SELECTOR', keyword_tab_CSS, 10, 'js')
+ # option_tab_XPATH = "//div[@id='rc-tabs-0-tab-3']"
+ # keyword_tab_CSS = ".ant-tabs-tab:nth-child(3)"
+ # click_element(driver, 'CSS_SELECTOR', keyword_tab_CSS, 10, 'js')
logger.debug("가격탭으로 이동 완료")
logger.debug("페이지 로딩 대기")
time.sleep(2) # 페이지 로딩 대기.
- option_high_price = product_infos.option_high_price
- option_low_price = product_infos.option_low_price
- # tao_high_price = product_infos.tao_high_price # 디버깅을 위해 선택된 옵션가격이 아닌 기존의 원래가격을 가져옴
- # tao_low_price = product_infos.tao_low_price # 디버깅을 위해 선택된 옵션가격이 아닌 기존의 원래가격을 가져옴
-
- naver_low_price = product_infos.naver_low_price
- naver_avg_price = product_infos.naver_avg_price
- naver_high_price = product_infos.naver_high_price
- w_delv_fee = product_infos.w_delv_fee
- packing_fee = product_infos.packing_fee
-
- inputs = {
- "option_low_price": option_low_price,
- "option_high_price": option_high_price,
- "delv_fee": w_delv_fee,
- "packing_fee": packing_fee,
- "ns_low_price": naver_low_price,
- "ns_high_price": naver_high_price
- }
- logger.debug(f"가격계산 INPUT 요소 : {inputs}")
+ try:
+ option_high_price = product_infos.option_high_price
+ option_low_price = product_infos.option_low_price
+
+ # tao_high_price = product_infos.tao_high_price # 디버깅을 위해 선택된 옵션가격이 아닌 기존의 원래가격을 가져옴
+ # tao_low_price = product_infos.tao_low_price # 디버깅을 위해 선택된 옵션가격이 아닌 기존의 원래가격을 가져옴
+
+ naver_low_price = product_infos.naver_low_price
+ naver_avg_price = product_infos.naver_avg_price
+ naver_high_price = product_infos.naver_high_price
+ w_delv_fee = product_infos.w_delv_fee
+ packing_fee = product_infos.packing_fee
+
+ inputs = {
+ "option_low_price": option_low_price,
+ "option_high_price": option_high_price,
+ "delv_fee": w_delv_fee,
+ "packing_fee": packing_fee,
+ "ns_low_price": naver_low_price,
+ "ns_high_price": naver_high_price
+ }
+ logger.debug(f"가격계산 INPUT 요소 : {inputs}")
+ except Exception as e:
+ logger.error(f"가격계산 INPUT 요소 계산 중 에러 발생 {e}", exc_info=True)
-
- outputs = calculate_margin_and_price(inputs)
- logger.debug(f"가격계산 OUTPUT 요소 : {outputs}")
-
- selling_price = outputs["selling_price"]
- final_margin_rate = outputs["final_margin_rate"]
- seller_cost = outputs["seller_cost"]
- plus_margin = outputs["plus_margin"]
- ns_avg_price = outputs["ns_avg_price"]
-
- return_fee = selling_price/2
-
- init_delv_fee = seller_cost
- exchange_fee = return_fee + init_delv_fee
+ try:
+ outputs = calculate_margin_and_price(inputs)
+ logger.debug(f"가격계산 OUTPUT 요소 : {outputs}")
+
+ selling_price = outputs["selling_price"]
+ final_margin_rate = outputs["final_margin_rate"]
+ seller_cost = outputs["seller_cost"]
+ plus_margin = outputs["plus_margin"]
+ ns_avg_price = outputs["ns_avg_price"]
+
+ return_fee = round((selling_price*0.4) / 1000) * 1000
+
+ init_delv_fee = seller_cost
+ exchange_fee = return_fee + init_delv_fee
- product_infos.plus_fee = plus_margin
- product_infos.return_fee = return_fee
- product_infos.init_delv_fee = init_delv_fee
- product_infos.exchange_fee = exchange_fee
+ product_infos.plus_fee = plus_margin
+ product_infos.return_fee = return_fee
+ product_infos.init_delv_fee = init_delv_fee
+ product_infos.exchange_fee = exchange_fee
+
+ logger.debug(f"결정된 상품가격: {selling_price}원, 최종 마진율: {final_margin_rate:.2f}%")
+ logger.debug(f"판매자 원가: {seller_cost}원")
+ logger.debug(f"더하기 마진: {plus_margin}원")
+ logger.debug(f"네이버 평균가: {ns_avg_price}원")
+ except Exception as e:
+ logger.error(f"가격계산 OUTPUT 요소 계산 중 에러 발생 {e}", exc_info=True)
- print(f"결정된 상품가격: {selling_price}원, 최종 마진율: {final_margin_rate:.2f}%")
- print(f"판매자 원가: {seller_cost}원")
- print(f"더하기 마진: {plus_margin}원")
- print(f"네이버 평균가: {ns_avg_price}원")
-
- # 가격 탭으로 이동
- logger.debug("내부함수 가격 탭으로 이동")
- thumb_tab_CSS = '.ant-tabs-tab:nth-child(3)'
- click_element(driver, 'CSS_SELECTOR', thumb_tab_CSS, 10, 'js')
- logger.debug("내부함수 가격 탭으로 이동 완료")
- logger.debug("페이지 로딩 대기")
- time.sleep(2) # 페이지 로딩 대기.
+ # # 가격 탭으로 이동
+ # logger.debug("내부함수 가격 탭으로 이동")
+ # thumb_tab_CSS = '.ant-tabs-tab:nth-child(3)'
+ # click_element(driver, 'CSS_SELECTOR', thumb_tab_CSS, 10, 'js')
+ # logger.debug("내부함수 가격 탭으로 이동 완료")
+ # logger.debug("페이지 로딩 대기")
+ # time.sleep(2) # 페이지 로딩 대기.
- logger.debug("더하기마진 수정")
- plus_fee_xpath="//div[@id='productMainContentContainerId']/div/div/div/div/div[2]/div/div/div[8]/div/div/div[3]/div/div/div/div/div[2]/input"
- plus_fee_element = return_element(driver, 'XPATH', plus_fee_xpath, 10)
- plus_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
- driver.execute_script("arguments[0].value = '';", plus_fee_element) # 기존 가격 삭제 JS
- logger.debug("기존가격 삭제")
- plus_fee_element.send_keys(plus_margin) # 새 가격 입력
- logger.debug(f"더하기마진 수정 완료 : {plus_margin}")
-
- logger.debug("해외배송비 수정")
- fore_delv_fee_xpath="//div[@id='productMainContentContainerId']/div/div/div/div/div[2]/div/div/div[10]/div/div/div/div/div[2]/input"
- fore_delv_fee_element = return_element(driver, 'XPATH', fore_delv_fee_xpath, 10)
- fore_delv_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
- driver.execute_script("arguments[0].value = '';", fore_delv_fee_element) # 기존 가격 삭제 JS
- logger.debug("기존가격 삭제")
- fore_delv_fee_element.send_keys(w_delv_fee) # 새 가격 입력
- logger.debug(f"해외배송비 수정 완료 : {w_delv_fee}")
-
- logger.debug("반품비 수정")
- return_fee_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[4]/div/div/div[3]/div/div/div/div/div[2]/input"
- return_fee_element = return_element(driver, 'XPATH', return_fee_xpath, 10)
- return_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
- driver.execute_script("arguments[0].value = '';", return_fee_element) # 기존 가격 삭제 JS
- logger.debug("기존가격 삭제")
- return_fee_element.send_keys(return_fee) # 새 가격 입력
- logger.debug(f"반품비 수정 완료 : {return_fee}")
-
- logger.debug("초도배송비 수정")
- first_delv_fee_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[4]/div/div/div[4]/div/div[2]/div/div/div[2]/input"
- first_delv_fee_element = return_element(driver, 'XPATH', first_delv_fee_xpath, 10)
- first_delv_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
- driver.execute_script("arguments[0].value = '';", first_delv_fee_element) # 기존 가격 삭제 JS
- logger.debug("기존가격 삭제")
- first_delv_fee_element.send_keys(init_delv_fee) # 새 가격 입력
- logger.debug(f"초도배송비 수정 완료 : {init_delv_fee}")
-
- logger.debug("교환비 수정")
- exchange_fee_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[4]/div/div/div[5]/div/div/div/div/div[2]/input"
- exchange_fee_element = return_element(driver, 'XPATH', exchange_fee_xpath, 10)
- exchange_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
- driver.execute_script("arguments[0].value = '';", exchange_fee_element) # 기존 가격 삭제 JS
- logger.debug("기존가격 삭제")
- exchange_fee_element.send_keys(exchange_fee) # 새 가격 입력
- logger.debug(f"교환비 수정 완료 : {exchange_fee}")
+ try:
+ logger.debug("더하기마진 수정")
+ plus_fee_xpath="//div[@id='productMainContentContainerId']/div/div/div/div/div[2]/div/div/div[8]/div/div/div[3]/div/div/div/div/div[2]/input"
+ plus_fee_element = return_element(driver, 'XPATH', plus_fee_xpath, 10)
+ plus_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
+ driver.execute_script("arguments[0].value = '';", plus_fee_element) # 기존 가격 삭제 JS
+ logger.debug("기존가격 삭제")
+ plus_fee_element.send_keys(plus_margin) # 새 가격 입력
+ logger.debug(f"더하기마진 수정 완료 : {plus_margin}")
+ except Exception as e:
+ logger.error(f"더하기마진 수정 중 에러 발생 {e}", exc_info=True)
+ try:
+ logger.debug("해외배송비 수정")
+ fore_delv_fee_xpath="//div[@id='productMainContentContainerId']/div/div/div/div/div[2]/div/div/div[10]/div/div/div/div/div[2]/input"
+ fore_delv_fee_element = return_element(driver, 'XPATH', fore_delv_fee_xpath, 10)
+ fore_delv_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
+ driver.execute_script("arguments[0].value = '';", fore_delv_fee_element) # 기존 가격 삭제 JS
+ logger.debug("기존가격 삭제")
+ fore_delv_fee_element.send_keys(w_delv_fee) # 새 가격 입력
+ logger.debug(f"해외배송비 수정 완료 : {w_delv_fee}")
+ except Exception as e:
+ logger.error(f"해외배송비 수정 중 에러 발생 {e}", exc_info=True)
+
+ try:
+ logger.debug("반품비 수정")
+ return_fee_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[4]/div/div/div[3]/div/div/div/div/div[2]/input"
+ return_fee_element = return_element(driver, 'XPATH', return_fee_xpath, 10)
+ return_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
+ driver.execute_script("arguments[0].value = '';", return_fee_element) # 기존 가격 삭제 JS
+ logger.debug("기존가격 삭제")
+ return_fee_element.send_keys(return_fee) # 새 가격 입력
+ logger.debug(f"반품비 수정 완료 : {return_fee}")
+ except Exception as e:
+ logger.error(f"반품비 수정 중 에러 발생 {e}", exc_info=True)
+
+ try:
+ logger.debug("초도배송비 수정")
+ first_delv_fee_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[4]/div/div/div[4]/div/div[2]/div/div/div[2]/input"
+ first_delv_fee_element = return_element(driver, 'XPATH', first_delv_fee_xpath, 10)
+ first_delv_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
+ driver.execute_script("arguments[0].value = '';", first_delv_fee_element) # 기존 가격 삭제 JS
+ logger.debug("기존가격 삭제")
+ first_delv_fee_element.send_keys(init_delv_fee) # 새 가격 입력
+ logger.debug(f"초도배송비 수정 완료 : {init_delv_fee}")
+ except Exception as e:
+ logger.error(f"초도배송비 수정 중 에러 발생 {e}", exc_info=True)
+
+ try:
+ logger.debug("교환비 수정")
+ exchange_fee_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[4]/div/div/div[5]/div/div/div/div/div[2]/input"
+ exchange_fee_element = return_element(driver, 'XPATH', exchange_fee_xpath, 10)
+ exchange_fee_element.send_keys(Keys.CLEAR) # 기존 가격 삭제
+ driver.execute_script("arguments[0].value = '';", exchange_fee_element) # 기존 가격 삭제 JS
+ logger.debug("기존가격 삭제")
+ exchange_fee_element.send_keys(exchange_fee) # 새 가격 입력
+ logger.debug(f"교환비 수정 완료 : {exchange_fee}`")
+ except Exception as e:
+ logger.error(f"교환비 수정 중 에러 발생 {e}", exc_info=True)
+
# logger.debug("기본마진율 수정")
# earning_rate_xpath = "//div[@id='productMainContentContainerId']/div/div/div/div/div[2]/div/div/div[8]/div/div/div/div/div/div/div/div[2]/input"
# earning_rate_element = return_element(driver, 'XPATH', earning_rate_xpath, 10, 'js')
@@ -142,6 +163,9 @@ def modify_price_page(driver, product_infos):
# 백그라운드 컬러로 빨간 가격탭 찾기
# background: rgb(255, 77, 79); box-shadow: none; color: rgb(255, 255, 255);
- save_xpath="//button[contains(.,'저장하기')]"
- click_element(driver, 'XPATH', save_xpath, 10)
- logger.debug("옵션 정리 후 저장버튼 클릭 완료")
+ try:
+ save_xpath="//button[contains(.,'저장하기')]"
+ click_element(driver, 'XPATH', save_xpath, 10)
+ logger.debug("가격 정리 후 저장버튼 클릭 완료")
+ except Exception as e:
+ logger.error(f"가격 정리 저장버튼 클릭 중 에러 발생 {e}", exc_info=True)
\ No newline at end of file
diff --git a/edit/price_cal.py b/edit/price_cal.py
index 51a0a13..743cab9 100644
--- a/edit/price_cal.py
+++ b/edit/price_cal.py
@@ -16,12 +16,14 @@ def calculate_margin_and_price(inputs):
plus_margin = 5000 # 기본값
# 계산 로직
- ns_avg_price = (ns_low_price + ns_high_price) / 2
+ ns_avg_price = round(((ns_low_price + ns_high_price) / 2) / 100) * 100
logger.debug(f"ns_avg_price : {ns_avg_price}")
- option_avg_price = (option_low_price + option_high_price) / 2
+ option_avg_price = round(((option_low_price + option_high_price) / 2) / 100) * 100
logger.debug(f"option_avg_price : {option_avg_price}")
- tao_cost = lambda price: price * 190 * 1.035
- base_margin = lambda cost: cost * 0.12
+ # tao_cost = lambda price: price * 190 * 1.035
+ tao_cost = lambda price: round(price * 1.035 / 100) * 100
+ base_margin = lambda cost: round(cost * 0.12 / 100) * 100
+
def adjust_plus_margin_for_min_margin(seller_cost, mall_cost, selling_price):
nonlocal plus_margin
@@ -32,16 +34,18 @@ def calculate_margin_and_price(inputs):
if final_margin_rate < target_margin_rate:
plus_margin += 100 # 더하기 마진 증가
selling_price = seller_cost + plus_margin + mall_cost
- mall_cost = selling_price * 0.13
+ mall_cost = round(selling_price * 0.13 / 100) * 100
else:
break
+
+ logger.debug(f"final_margin_rate : {final_margin_rate}")
return selling_price, final_margin_rate
seller_cost = tao_cost(option_avg_price) + delv_fee + packing_fee
logger.debug(f"seller_cost : {seller_cost}")
- mall_cost = seller_cost * 0.13
+ mall_cost = round((seller_cost * 0.13)/100) * 100
selling_price = seller_cost + plus_margin + mall_cost
selling_price, final_margin_rate = adjust_plus_margin_for_min_margin(seller_cost, mall_cost, selling_price)
diff --git a/img_trans/image_trans.py b/img_trans/image_trans.py
index 936874c..b492ac3 100644
--- a/img_trans/image_trans.py
+++ b/img_trans/image_trans.py
@@ -68,8 +68,10 @@ def image_trans(image_url, convert_type):
# 번역된 텍스트 추출 및 삽입
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"DEEPL 번역시작")
+ translated_texts = translate_texts_deepl(texts_to_translate)
if not translated_texts: # 빈 리스트 체크
+ logger.debug(f"DEEPL 번역실패로 translatepy 시작")
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)
diff --git a/img_trans/src/translation.py b/img_trans/src/translation.py
index ad49aa1..f7eebaa 100644
--- a/img_trans/src/translation.py
+++ b/img_trans/src/translation.py
@@ -1,6 +1,7 @@
from googletrans import Translator
# from img_trans.src.deepl_ori import trans
from ai.deepl import trans
+from ai.deepl_with_playwright import trans_list_text, trans_text
from translatepy import Translator
import logging
@@ -21,7 +22,7 @@ def translate_texts_google(texts, src_lang='zh-cn', dest_lang='ko'):
return translated_texts
-def translate_texts_deepl(texts):
+def translate_texts_deepl_ori(texts):
"""텍스트 리스트를 지정된 언어에서 다른 언어로 번역"""
# 텍스트 리스트를 엔터로 구분된 하나의 문자열로 합침
combined_text = "\n".join(texts)
@@ -29,18 +30,34 @@ def translate_texts_deepl(texts):
# DeepL로 전체 텍스트 번역
try:
- translated_combined_text = trans(combined_text)
+ # translated_combined_text = trans(combined_text)
+ translated_combined_text = trans_list_text(combined_text)
for translation in translated_combined_text:
# "가격"이 포함된 경우 빈 문자열로 대체
translated_texts.append(translation.text if "가격" not in translation.text else "")
# 번역된 전체 텍스트를 엔터를 기준으로 분리하여 리스트로 만듦
translated_texts = translated_combined_text.split("\n")
except AttributeError as e:
- logger.error(f"번역 실패: {e}")
+ logger.error(f"번역 실패: {e}", exc_info=True)
translated_texts = []
return translated_texts
+def translate_texts_deepl(texts):
+ """텍스트 리스트를 지정된 언어에서 다른 언어로 번역"""
+ translated_texts = []
+
+ # DeepL로 전체 텍스트 번역
+ try:
+ translated_texts = trans_list_text(texts)
+ # "가격"이 포함된 경우 빈 문자열로 대체
+ translated_texts = [text if "가격" not in text else "" for text in translated_texts]
+
+ except AttributeError as e:
+ logger.error(f"번역 실패: {e}", exc_info=True)
+ translated_texts = []
+
+ return translated_texts
def translate_texts_translatepy(texts, src_lang='zh-cn', dest_lang='ko'):
"""translatepy 라이브러리를 사용하여 텍스트 리스트를 번역합니다."""
diff --git a/login_widget.py b/login_widget.py
index 06336f5..ec06f21 100644
--- a/login_widget.py
+++ b/login_widget.py
@@ -51,7 +51,7 @@ class LoginWidget(QtWidgets.QWidget):
# self.setGeometry(780, 420, 240, 200)
# 위젯의 크기를 설정합니다.
- self.resize(800, 800)
+ self.resize(400, 600)
self.center() # 화면 가운데에 위치시키는 메서드
# 레이아웃 설정
@@ -124,6 +124,10 @@ class LoginWidget(QtWidgets.QWidget):
self.loginButton = QtWidgets.QPushButton("로그인")
self.loginButton.clicked.connect(self.login)
+
+ self.DeleteDB_by_ID = QtWidgets.QLineEdit()
+ self.DeleteDB_by_ID.setPlaceholderText("상품ID 입력시 해당 DB 삭제")
+
self.alwaysOnTopSwitch = ToggleSwitch(self)
self.alwaysOnTopSwitch.move(10, 10)
@@ -220,13 +224,13 @@ class LoginWidget(QtWidgets.QWidget):
# label = QtWidgets.QLabel(label_text)
# setting_layout.addWidget(label) # 설명 라벨은 2열(인덱스 1)에 배치
- setting_layout.addLayout(self.modifyProductNameSwitch_layout)
- setting_layout.addLayout(self.modifyProductOptionsSwitch_layout)
- setting_layout.addLayout(self.modifyProductPriceSwitch_layout)
setting_layout.addLayout(self.modifyProductTagSwitch_layout)
setting_layout.addLayout(self.modifyProductThumbSwitch_layout)
+ setting_layout.addLayout(self.modifyProductOptionsSwitch_layout)
setting_layout.addLayout(self.modifyProductDetailSwitch_layout)
setting_layout.addLayout(self.modifyImageTranslationSwitch_layout)
+ setting_layout.addLayout(self.modifyProductPriceSwitch_layout)
+ setting_layout.addLayout(self.modifyProductNameSwitch_layout)
setting_layout.addLayout(self.uploadToMarketSwitch_layout)
setting_layout.addLayout(self.alwaysOnTopSwitch_layout)
setting_layout.addLayout(self.shutdownSwitch_layout)
diff --git a/main.py b/main.py
index d4b3e3a..2f71135 100644
--- a/main.py
+++ b/main.py
@@ -5,7 +5,7 @@ from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service #웨일
# from webdriver_manager.chrome import ChromeDriverManager #웨일
import time
-import datetime
+from datetime import datetime
import ctypes
import atexit
import platform, os, sys
@@ -39,7 +39,7 @@ def prevent_sleep_mode():
ES_CONTINUOUS |
ES_SYSTEM_REQUIRED
)
-
+
# 시스템 절전 모드 방지 해제
def restore_sleep_mode():
ES_CONTINUOUS = 0x80000000
@@ -114,7 +114,10 @@ def DB_setting():
"whether_uploadToMarket": login_widget.whether_uploadToMarket,
"login_result": login_widget.result,
}
-
+
+ tag = login_info["whether_modifyImageTanslation"]
+
+ logger.debug(f"whether_modifyImageTanslation : {tag}")
return login_info, result, mongo_config
def main():
@@ -127,7 +130,7 @@ def main():
atexit.register(restore_sleep_mode)
atexit.register(record_logout_time)
- if login_info.whether_shutdownAfterComplete:
+ if login_info["whether_shutdownAfterComplete"]:
atexit.register(shutdown_system)
atexit.register(send_exit_message)
diff --git a/modify_products.py b/modify_products.py
index 02ede56..ba26910 100644
--- a/modify_products.py
+++ b/modify_products.py
@@ -181,6 +181,18 @@ def modify_products(driver, gemini, mongo_config, login_info, set_num_modify):
logger.debug(f"{current_page}페이지-{i}번 상품 수정시작")
product_infos.append(ProductInfo())
# 1번 상품과 나머지 상품들에 대한 XPATH 처리
+
+ # 상품 수정 관련 작업을 조건에 따라 수행하는 로직
+ 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"],
+ }
steps_and_actions = [
('tag_modification', edit_tag, (driver, product_infos[i-1])),
@@ -189,21 +201,10 @@ def modify_products(driver, gemini, mongo_config, login_info, set_num_modify):
('detail_page_modification', modify_detail_page, (driver, product_infos[i-1], gemini, delv_collection, json_naver_codes, login_info)),
('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])),
+ # ('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:
diff --git a/naver_search.py b/naver_search.py
index 2977edf..fc854f0 100644
--- a/naver_search.py
+++ b/naver_search.py
@@ -56,11 +56,11 @@ def parse_naver_shopping(keyword, naver_code, isOverseas=1, sortcount=10):
logger.debug("NEXT_DATA JSON을 파싱하는 중 오류 발생:", e)
# 예외 처리 코드 추가
- # "__NEXT_DATA__" 파싱하기
- logger.debug("NEXT_DATA 파싱 완료")
+ # # "__NEXT_DATA__" 파싱하기
+ # logger.debug("NEXT_DATA 파싱 완료")
- next_data_str = soup.find("script", {"id": "__NEXT_DATA__"}).string
- next_data_json = json.loads(next_data_str)
+ # next_data_str = soup.find("script", {"id": "__NEXT_DATA__"}).string
+ # next_data_json = json.loads(next_data_str)
# products 리스트 가져오기
logger.debug("products 리스트 가져오기")