AutoPercenty/ai/deepl_with_playwright.py

149 lines
8.5 KiB
Python

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 모드로 실행
# 동영상 녹화 설정을 포함하여 브라우저 컨텍스트 생성
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/translator#zh/ko/'+ original_text)
# 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_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"]')
# 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 context: # context가 초기화되었는지 확인하고, 종료
context.close()
if browser: # browser가 초기화되었는지 확인하고, 종료
browser.close()
logger.info("playwright Browser 닫힘.")
return translated_text
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;
editor.dispatchEvent(new Event('input', {bubbles: true}));
editor.dispatchEvent(new Event('keydown', {bubbles: true}));
editor.dispatchEvent(new Event('keyup', {bubbles: true}));
editor.dispatchEvent(new Event('keypress', {bubbles: true}));
}""", text)
# 번역이 완료될 때까지 기다림
page.wait_for_function("document.querySelector(\"[data-testid='translator-target-input']\").textContent.length > 0", timeout=20000)
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}")