1
0
Fork 0

가져오기

This commit is contained in:
R5600U_PC 2024-04-08 10:14:18 +09:00
parent 72e042ec03
commit ae190ca8cf
16 changed files with 4642 additions and 27 deletions

View File

@ -8,12 +8,44 @@ from selenium.webdriver.support import expected_conditions as EC
from tqdm import tqdm
from selenium_stealth import stealth
from fake_useragent import UserAgent
import random
import logging
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
def trans(original_text):
# PC 사용자 에이전트
USER_AGENTS = [
# Chrome (Windows 10)
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
# Edge (Windows 10)
"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",
# Firefox (Windows 10)
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0",
# Safari (macOS Monterey)
"Mozilla/5.0 (Macintosh; Intel Mac OS X 12_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
# Opera (Windows 10)
"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)
# Start a Selenium driver
options = webdriver.ChromeOptions()
ua = UserAgent()
options.add_argument(f"--user-agent={ua.random}") # 랜덤 user_agent 사용
# ua = UserAgent()
# ua.user_agent_list = ua.pc_browsers
# # 랜덤 PC Agent 선택
# random_PC_UA = ua.random
# logger.debug(f"UserAgent : {random_PC_UA}")
# options.add_argument(f"--user-agent={random_PC_UA}") # 랜덤 user_agent 사용
options.add_argument(f"user-agent={random_user_agent}")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ssl-protocol=any')
@ -32,22 +64,19 @@ def trans(original_text):
)
# Reach the deepL website
options.headless = False # 헤드리스 모드 선택적 비활성화
deepl_url = 'https://www.deepl.com/ko/translator' # 한국어
driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => undefined})") # 속성 변경
driver.get(deepl_url)
# Define text to translate
# texts_to_translate = [
# 'Shuffle data after an epoch!',
# 'StaleElementReferenceException: Message: stale element reference: element is not attached to the page document',
# 'Hello python!',
# 'Using Selenium and deepL to automate the translation!'
# ]
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="translator-source-input"]'))).send_keys(original_text)
WebDriverWait(driver, 20).until(lambda d: d.execute_script('return document.readyState') == 'complete')
# for text_to_translate in tqdm(original_text):
# WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".min-h-0:nth-child(1) > div:nth-child(1)"))).send_keys(original_text)
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-testid="translator-source-input"]'))).send_keys(original_text)
time.sleep(3) # Adjust sleep time based on network speed and response time
time.sleep(4) # Adjust sleep time based on network speed and response time
# Improved wait for translation to appear
try:
@ -56,7 +85,7 @@ def trans(original_text):
translation_text = driver.find_element(By.CSS_SELECTOR, '[data-testid="translator-target-input"]')
content = translation_text.text
except Exception as e:
print("Error fetching translation:", e)
logger.error(f"Error fetching translation:{e}", exc_info=True)
content = "Translation failed"
# Display results

88
ai/deepl2.py Normal file
View File

@ -0,0 +1,88 @@
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from tqdm import tqdm
from selenium_stealth import stealth
from fake_useragent import UserAgent
import random
import logging
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
def trans(original_text):
# PC 사용자 에이전트
USER_AGENTS = [
# Chrome (Windows 10)
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
# Edge (Windows 10)
"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",
# Firefox (Windows 10)
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:108.0) Gecko/20100101 Firefox/108.0",
# Safari (macOS Monterey)
"Mozilla/5.0 (Macintosh; Intel Mac OS X 12_0) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Safari/605.1.15",
# Opera (Windows 10)
"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)
# Start a Selenium driver
options = webdriver.ChromeOptions()
# ua = UserAgent()
# ua.user_agent_list = ua.pc_browsers
# # 랜덤 PC Agent 선택
# random_PC_UA = ua.random
# logger.debug(f"UserAgent : {random_PC_UA}")
# options.add_argument(f"--user-agent={random_PC_UA}") # 랜덤 user_agent 사용
options.add_argument(f"user-agent={random_user_agent}")
options.add_argument("--disable-blink-features=AutomationControlled")
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ssl-protocol=any')
options.add_argument('--disable-cache')
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
# selenium-stealth 설정 적용
stealth(driver,
languages=["en-US", "en"],
vendor="Google Inc.",
platform="Win32",
webgl_vendor="Intel Inc.",
renderer="Intel Iris OpenGL Engine",
fix_hairline=True,
)
# Reach the deepL website
# deepl_url = 'https://www.deepl.com/ko/translator' # 한국어
# driver.get(deepl_url)
deepl_trans_url = "https://www.deepl.com/ko/translator#zh/ko/" + original_text
driver.get(deepl_trans_url)
time.sleep(4)
try:
WebDriverWait(driver, 10).until(
lambda driver: driver.find_element(By.CSS_SELECTOR, '[data-testid="translator-target-input"]').text.strip() != "")
translation_text = driver.find_element(By.CSS_SELECTOR, '[data-testid="translator-target-input"]')
content = translation_text.text
except Exception as e:
logger.error(f"Error fetching translation:{e}", exc_info=True)
content = "Translation failed"
driver.quit()
return content

View File

@ -0,0 +1,74 @@
from playwright.sync_api import sync_playwright
import random
import logging
# 로거 인스턴스 가져오기
logger = logging.getLogger('default_logger')
def trans_text(original_text):
with sync_playwright() as p:
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)
page = context.new_page()
# DeepL 웹사이트 접속
page.goto('https://www.deepl.com/ko/translator')
# JavaScript를 사용하여 편집 가능한 div에 텍스트 입력
page.evaluate("""(text) => {
const editor = document.querySelector('[data-testid="translator-source-input"] div[contenteditable="true"]');
editor.textContent = text;
}""", original_text)
# 번역이 완료될 때까지 대기
# state 상태
# "attached": 요소가 DOM에 삽입되어 있음을 의미합니다. 요소가 페이지에 추가되었지만, 반드시 화면에 보이는 것은 아닙니다.
# "detached": 요소가 DOM에서 제거되었음을 의미합니다.
# "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_selector('[data-testid="translator-target-input"]', state="visible", timeout=10000)
translated_text = page.text_content('[data-testid="translator-target-input"]')
# translated_text = page.input_value('[data-testid="translator-target-input"]')
# page.text_content(selector[, options])
# 이 메서드는 지정된 선택자와 일치하는 요소의 textContent 속성 값을 반환합니다.
# 주로 <div>, <span>, <p>와 같은 텍스트를 포함할 수 있는 비입력 요소의 내용을 가져올 때 사용됩니다.
# 요소가 없거나 텍스트가 없는 경우 None을 반환할 수 있습니다.
# 예: 페이지의 특정 섹션에서 사용자에게 보이는 텍스트를 추출할 때 사용됩니다.
# page.input_value(selector[, options])
# 이 메서드는 <input>, <textarea>, <select>와 같은 입력 요소의 현재 값을 반환합니다.
# 입력 필드에 사용자 또는 스크립트에 의해 입력되거나 선택된 값을 얻을 때 사용됩니다.
# 이 메서드는 주로 사용자 입력을 처리하는 폼 필드에서 값을 가져올 때 사용됩니다.
# 결과 로깅 및 반환
logger.info(f"playwright 받은 원본 텍스트 : {original_text}")
logger.info(f"playwright 받은 번역 텍스트 : {translated_text}")
except Exception as e:
logger.error(f"An error occurred: {e}", exc_info=True)
return "에러발생으로 인한 번역 실패."
finally:
if browser: # browser가 초기화되었는지 확인
browser.close()
logger.info("playwright Browser 닫힘.")
return translated_text

View File

@ -24,13 +24,35 @@ class ImageDescriptionGenerator:
while len(nv_products) < required_length:
nv_products.append(default_product)
logger.debug(f"{len(nv_products)}번째 상품정보가 없어 기본정보로 채웁니다.")
def fill_product_info_lists(self, product_info, required_length=5):
# naver_products 리스트 채우기
nv_products = product_info.naver_products
default_product = {"productTitle": "상품 정보 없음", "price": "가격 정보 없음"}
while len(nv_products) < required_length:
nv_products.append(default_product)
logger.debug(f"{len(nv_products)}번째 상품정보가 없어 기본정보로 채웁니다.")
# trans_option_1_names 리스트 채우기
while len(product_info.trans_option_1_names) < required_length:
product_info.trans_option_1_names.append("옵션 정보 없음")
logger.debug(f"{len(product_info.trans_option_1_names)}번째 trans_option_1_names 정보가 없어 기본정보로 채웁니다.")
# trans_option_2_names 리스트 채우기
if hasattr(product_info, 'trans_option_2_names'):
while len(product_info.trans_option_2_names) < required_length:
product_info.trans_option_2_names.append("옵션 정보 없음")
logger.debug(f"{len(product_info.trans_option_2_names)}번째 trans_option_2_names 정보가 없어 기본정보로 채웁니다.")
def generate_description(self, product_info, top_k=3):
"""이미지 URL을 받아 해당 이미지에 대한 설명을 생성하고 반환합니다."""
# 'gemini-pro-vision' 모델을 사용하여 이미지 설명 생성
# prompt = f"이미지의 상품명은 {title} 1. 이 상품이 무엇인지, 어떤 용도로 사용하는지 설명해줘 2. 이 상품의 배송비 산정을 위해 대략적인 무게를 kg으로 단답형으로 추정해줘. 3. 이 이미지의 상품을 한국의 온라인 쇼핑몰에서 팔기위한 홍보문구를 상품이미지에 맞게 3줄 ~ 4줄 정도 만들어줘. 4.대답하는 방식은 [상품의 홍보문구] 여러줄, [상품의 용도] 자세히, [상품의 무게] 형식과 순서로 해줘."
# prompt = f"주어진 이미지의 상품명은 {product_info.keyword_title} 1. 이 상품이 무엇인지, 어떤 용도로 사용하는지 설명해줘 2. 이 상품의 배송비 산정을 위해 대략적인 무게를 kg으로 단답형으로 추정해줘. 3. 이 이미지의 상품을 한국의 온라인 쇼핑몰에서 팔기위한 홍보문구를 상품이미지에 맞게 3줄 ~ 4줄 정도 만들어줘."
self.fill_naver_products(product_info)
# self.fill_naver_products(product_info)
self.fill_product_info_lists(product_info)
prompt = f'''
주어진 상품 이미지에 대한 정보를 줄께.

20
build.py Normal file
View File

@ -0,0 +1,20 @@
import shutil
import os
from subprocess import call
# 삭제할 디렉토리 목록
folders_to_delete = ['build', 'dist']
# 현재 디렉토리 내의 폴더들을 순회하며 삭제
for folder in folders_to_delete:
if os.path.exists(folder):
shutil.rmtree(folder)
print(f"{folder} 폴더를 삭제했습니다.")
# PyInstaller 명령 실행
# 여기에서 'your_script.py'를 실제 빌드하고자 하는 스크립트의 이름으로 바꿔주세요.
# 추가 PyInstaller 옵션이 필요한 경우 이 부분에 추가합니다.
# 디버깅용 : main.spec
# 배포용 : AutoPercenty.spec
call(['pyinstaller', 'main.spec'])

BIN
dist_file/NotoSans.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

6
dist_file/config.ini Normal file
View File

@ -0,0 +1,6 @@
[MongoDB]
address = cckb9998.synology.me
port = 27017
user = root
password = 1234

BIN
dist_file/simfang.ttf Normal file

Binary file not shown.

View File

@ -609,6 +609,8 @@ 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("") 또는 아무 동작도 수행하지 않음

View File

@ -6,6 +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.compare import find_most_similar_image_by_one
import re
import logging
@ -265,6 +266,7 @@ def option_name_trans(driver, product_info, option_type_number, option_count, al
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 번역 함수
logger.debug(f"번역된 텍스트 \n {trans_optionNames_text} ")

View File

@ -3,7 +3,7 @@
import os
# 현재 .spec 파일의 디렉토리 경로를 가져옵니다.
spec_dir = os.path.dirname(os.path.abspath(__file__))
spec_dir = os.path.dirname(os.path.abspath(__name__))
# 이 경로를 기준으로 다른 경로들을 지정
#icon_path = os.path.join(spec_dir, 'icons', 'app_icon.ico')
@ -18,14 +18,16 @@ a = Analysis(
(os.path.join(spec_dir, 'Lib', 'site-packages', 'paddleocr'), 'paddleocr'),
(os.path.join(spec_dir, 'models'), 'models'),
(os.path.join(spec_dir, 'Lib', 'site-packages', 'paddle', 'libs', '*.dll'), 'paddle\\libs'),
(os.path.join(spec_dir, 'config.ini'), '.')
(os.path.join(spec_dir, 'NotoSansKR-Bold.ttf'), '.')
(os.path.join(spec_dir, 'NotoSans.ttf'), '.')
(os.path.join(spec_dir, 'NotoSansKR-ExtraBold.ttf'), '.')
(os.path.join(spec_dir, 'NotoSansKR-Regular.ttf'), '.')
(os.path.join(spec_dir, 'NotoSansKR-SemiBold.ttf'), '.')
(os.path.join(spec_dir, 'simfang.ttf'), '.')
(os.path.join(spec_dir, 'Percenty_SS_Code.json'), '.')
(os.path.join(spec_dir, 'Lib', 'site-packages', 'selenium_stealth'), 'selenium_stealth'),
(os.path.join(spec_dir, 'Lib', 'site-packages', 'fake_useragent'), 'fake_useragent'),
(os.path.join(spec_dir, 'config.ini'), '.'),
(os.path.join(spec_dir, 'Percenty_SS_Code.json'), '.'),
(os.path.join(spec_dir, 'NotoSansKR-Bold.ttf'), '.'),
(os.path.join(spec_dir, 'NotoSans.ttf'), '.'),
(os.path.join(spec_dir, 'NotoSansKR-ExtraBold.ttf'), '.'),
(os.path.join(spec_dir, 'NotoSansKR-Regular.ttf'), '.'),
(os.path.join(spec_dir, 'NotoSansKR-SemiBold.ttf'), '.'),
(os.path.join(spec_dir, 'simfang.ttf'), '.'),
],
hiddenimports=[
'shapely', 'pyclipper', 'imghdr', 'skimage', 'skimage.morphology._skeletonize', 'imgaug', 'scipy.io', 'lmdb', 'tqdm', 'paddlepaddle.core'
@ -52,8 +54,7 @@ exe = EXE(
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
onefile=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,