编程 · 2025 年 1 月 13 日 0

用python通过papago网页版翻译韩语成中文txt格式

手头有一些韩语同人文, 翻了一下,第一篇就有二十多万个字符。
想要先机翻一下再调整润色一下。用韩语翻译比较准确的papgo翻译,但每次只能输入3千个字符。整篇翻译下来要复制粘贴几十次,所以想写个脚本来处理一下。

一开始的想法是通过papago翻译时候的接口来获取结果,但是在尝试的过程当中发现接口好像有做状态校验,还是加密过的,不知道key是什么无法破解,感觉为了一个简单的脚本去写破解也太麻烦了。
接着想申请papago的官方接口来处理,结果去申请的时候,最后因为没有韩国的手机号码卡住了。
最后想到可以用脚本模拟浏览器行为来处理,用到的是webdriver的库。
思路是,找到输入框、翻译按钮、输出框的id,逐句从txt里面把句子取出来,放到输入框里面,再点击翻译按钮,最后把输出框的内容输出。

一开始的代码

# 初始化浏览器驱动
driver = webdriver.Chrome()  

# 打开 Papago 网站
driver.get("https://papago.naver.com/")

# 等待页面加载完成
time.sleep(5)

# 定位输入框和翻译按钮
input_box = driver.find_element(By.ID, "txtSource")
translate_button = driver.find_element(By.ID, "btnTranslate")

# 逐段翻译并保存结果
translated_texts = []
for paragraph in paragraphs:
    paragraph = paragraph.strip()  # 去除空白字符
    if not paragraph:  # 跳过空行
        translated_texts.append(paragraph)
        continue
# 清空输入框并输入段落
    input_box.clear()
    input_box.send_keys(paragraph)

    # 点击翻译按钮
    translate_button.click()

# 动态等待翻译结果加载完成
	try:
	 # 获取初始的翻译结果
	 initial_translation = driver.find_element(By.ID, "txtTarget").text

	# 等待翻译结果变化(增加等待时间到 30 秒)
	WebDriverWait(driver, 30).until(
	lambda driver: driver.find_element(By.ID, "txtTarget").text != initial_translation
            )

	# 获取最终的翻译结果
	utput_box = driver.find_element(By.ID, "txtTarget")
	translated_text = output_box.text
	translated_texts.append(translated_text)
	break  # 翻译成功,退出重试循环

# 确保所有内容都被翻译后关闭浏览器
driver.quit()

过程中发现几个问题
1.有时候因为网络问题翻译没有返回结果,就翻译失败了。因为前面判断翻译成功的逻辑是判断翻译结果id内容的变化,如果没有变化就默认失败。对此加了重试。

max_retries = 3
    retry_count = 0
    while retry_count < max_retries:
	try:
		...
	        except TimeoutException:
            retry_count += 1
            if retry_count == max_retries:
                print(f"翻译超时(重试 {max_retries} 次): {paragraph}")
                translated_texts.append(f"[翻译失败: {paragraph}]")
            else:
                print(f"翻译超时,正在重试({retry_count}/{max_retries}): {paragraph}")

2.加了重试后发现有一些无需翻译的内容也要重试3次,比如链接,和一些仅有符号的句子(“!!”或者“……“拖慢了速度。所以加了一个正则表达式去判断句子是否无需翻译,如果无需翻译就直接保存原句。

# 定义无需翻译的正则表达式(如空行、空格、仅有数字、仅有符号、仅有数字+符号、链接或链接+符号)
no_translate_pattern = re.compile(
    r'^\s*$|'  # 空行或仅包含空格
    r'^[\d\s“”‘’\"\'\.,;:!?]*$|'  # 仅有数字、空格或符号
    r'^[\s“”‘’\"\'\.,;:!?]*(https?://|www\.)\S+|'  # 符号加链接
    r'^(https?://|www\.)\S+[\s“”‘’\"\'\.,;:!?]*$|'  # 链接加符号
    r'^[\s“”‘’\"\'\.,;:!?]*(https?://|www\.)\S+[\s“”‘’\"\'\.,;:!?]*$'  # 符号加链接再加符号
)

# 判断是否需要翻译
    if no_translate_pattern.match(paragraph):
        print(f"无需翻译: {paragraph}")  # 打印调试信息
        translated_texts.append(paragraph)
        continue

3.还想知道单个文件执行完翻译大概需要多长时间就加了一个时间打印

start_time = time.time()
# 计算总花费时间
......

# 将秒数转换为易读的时间格式
def format_time(seconds):
    if seconds < 60:
        return f"{int(seconds)}秒"
    elif seconds < 3600:
        minutes = int(seconds // 60)
        seconds = int(seconds % 60)
        return f"{minutes}分{seconds}秒"
    else:
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        seconds = int(seconds % 60)
        return f"{hours}小时{minutes}分{seconds}秒"

end_time = time.time()
total_time = end_time - start_time

# 格式化总耗时
formatted_time = format_time(total_time)

# 打印完成信息和总花费时间
print(f"已输出文件,总耗时 {formatted_time}")

中间运行的时候还遇到了一个小插曲:翻译文件的时候发现从某一句开始译文变成了英文。一开始我以为是代码哪里被我动到了。找了半天都没找到问题。把每一次翻译都加了个语言的判断,速度一下变慢了很多。后面定位开始句子才发现是因为文件里面有一句是中文。如果你在韩译汉的输入框输入中文,翻译语言也是中文的时候,正常是不会有变化,但下一句输入韩文时它检测到变化就会把翻译结束的语种改为你默认的语言。因为我的浏览器语言默认设置是英文,就默认切到了英文。这一步其实修改默认的系统语言就能解决。

使用感受是一句句翻译能保留格式但是句子里面人名什么的容易变形,会有N多不同的结果,并且没有上下文,同音字翻译错的概率也上升了很多。

最后

附上hwp转txt的网站一个:https://cloudconvert.com/hwp-to-txt

单次可以同时处理5个文件,每天可以免费处理10个文件

完整代码

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException  # 新增异常捕获
import time
import re

# 记录脚本开始时间
start_time = time.time()

# 读取 input.txt 文件
with open("input.txt", "r", encoding="utf-8") as file:
    paragraphs = file.readlines()

# 初始化浏览器驱动
driver = webdriver.Chrome()  # 如果 chromedriver 不在系统路径中,可以指定路径:webdriver.Chrome("/path/to/chromedriver")

# 打开 Papago 网站
driver.get("https://papago.naver.com/")

# 等待页面加载完成
time.sleep(3)

# 设置目标语言为简体中文
try:
    # 点击目标语言下拉框
    target_lang_dropdown = driver.find_element(By.XPATH, '//div[@id="ddTargetLanguage"]')
    target_lang_dropdown.click()

    # 打印目标语言下拉框的 HTML 结构(调试用)
    #print("目标语言下拉框 HTML:", target_lang_dropdown.get_attribute("innerHTML"))
    time.sleep(2) 

    # 使用完整的 XPath 定位简体中文选项
    chinese_option = driver.find_element(By.XPATH, '/html/body/div/div/div[1]/section/div/div[2]/div[2]/div/div[2]/div[2]/div/div[2]/ul/li[4]/a/span')
    chinese_option.click()

    # 等待语言切换完成
    time.sleep(1)
except Exception as e:
    print("设置目标语言失败:", e)
    driver.quit()
    exit()

# 定位输入框和翻译按钮
input_box = driver.find_element(By.ID, "txtSource")
translate_button = driver.find_element(By.ID, "btnTranslate")

# 定义无需翻译的正则表达式(如空行、空格、仅有数字、仅有符号、仅有数字+符号、链接或链接+符号)
no_translate_pattern = re.compile(
    r'^\s*$|'  # 空行或仅包含空格
    r'^[\d\s“”‘’\"\'\.,;:!?]*$|'  # 仅有数字、空格或符号
    r'^[\s“”‘’\"\'\.,;:!?]*(https?://|www\.)\S+|'  # 符号加链接
    r'^(https?://|www\.)\S+[\s“”‘’\"\'\.,;:!?]*$|'  # 链接加符号
    r'^[\s“”‘’\"\'\.,;:!?]*(https?://|www\.)\S+[\s“”‘’\"\'\.,;:!?]*$'  # 符号加链接再加符号
)

# 将秒数转换为易读的时间格式
def format_time(seconds):
    if seconds < 60:
        return f"{int(seconds)}秒"
    elif seconds < 3600:
        minutes = int(seconds // 60)
        seconds = int(seconds % 60)
        return f"{minutes}分{seconds}秒"
    else:
        hours = int(seconds // 3600)
        minutes = int((seconds % 3600) // 60)
        seconds = int(seconds % 60)
        return f"{hours}小时{minutes}分{seconds}秒"

# 逐段翻译并保存结果
translated_texts = []
for paragraph in paragraphs:
    paragraph = paragraph.strip()  # 去除空白字符
    if not paragraph:  # 跳过空行
        translated_texts.append(paragraph)
        continue

    # 判断是否需要翻译
    if no_translate_pattern.match(paragraph):
        print(f"无需翻译: {paragraph}")  # 打印调试信息
        translated_texts.append(paragraph)
        continue

    # 清空输入框并输入段落
    input_box.clear()
    input_box.send_keys(paragraph)

    # 点击翻译按钮
    translate_button.click()

    # 动态等待翻译结果加载完成
    max_retries = 3
    retry_count = 0
    while retry_count < max_retries:
        try:
            # 获取初始的翻译结果
            initial_translation = driver.find_element(By.ID, "txtTarget").text

            # 等待翻译结果变化(增加等待时间到 30 秒)
            WebDriverWait(driver, 30).until(
                lambda driver: driver.find_element(By.ID, "txtTarget").text != initial_translation
            )

            # 获取最终的翻译结果
            output_box = driver.find_element(By.ID, "txtTarget")
            translated_text = output_box.text
            translated_texts.append(translated_text)
            break  # 翻译成功,退出重试循环
        except TimeoutException:
            retry_count += 1
            if retry_count == max_retries:
                print(f"翻译超时(重试 {max_retries} 次): {paragraph}")
                translated_texts.append(f"[翻译失败: {paragraph}]")
            else:
                print(f"翻译超时,正在重试({retry_count}/{max_retries}): {paragraph}")
        except NoSuchElementException:
            print(f"元素未找到: {paragraph}")
            translated_texts.append(f"[翻译失败: {paragraph}]")
            break
        except Exception as e:
            print(f"翻译出错: {e}")
            translated_texts.append(f"[翻译失败: {paragraph}]")
            break

# 确保所有内容都被翻译后关闭浏览器
driver.quit()

# 将翻译结果保存到 output.txt
with open("output.txt", "w", encoding="utf-8") as file:
    file.write("\n".join(translated_texts))

# 计算总花费时间
end_time = time.time()
total_time = end_time - start_time

# 格式化总耗时
formatted_time = format_time(total_time)

# 打印完成信息和总花费时间
print(f"已输出文件,总耗时 {formatted_time}")