forked from ckh08045/AutoPercenty
145 lines
8.3 KiB
Python
145 lines
8.3 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;
|
|
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}") |