文档智能翻译,保留文档原有布局,版式还原

news2025/1/13 0:21:55

翻译能力:

  1. 使用讯飞的AI翻译能力:机器翻译 niutrans - 语音扩展 - 讯飞开放平台
  2. API: 机器翻译niutrans API 文档 | 讯飞开放平台文档中心
执行效果:

    原文档:

   翻译还原的文档:

源码如下:

import datetime
import hashlib
import base64
import hmac
import json
import requests
import threading
from threading import Thread
from queue import Queue, Full, Empty
from docx import Document
from concurrent.futures import ThreadPoolExecutor

# 全局配置
APPId = "xxx"
APISecret = "xxxx"
APIKey = "xxxx"
HOST = "ntrans.xfyun.cn"


# 线程池
class ThreadPool:
    def __init__(self, size: int, max_workers: int):
        self.max_workers = max_workers  # 最大可运行线程数
        self._has_th = []  # 已启动线程数
        self._pending = Queue(maxsize=max_workers)  # 阻塞线程数
        self._task = Queue(maxsize=size)  # 任务等待队列
        self._close = False  # 线程池是否关闭

    def worker(self, *args):
        """
        任务的执行者
        :param args: 运行任务与任务参数
        :return:
        """
        th = threading.current_thread()
        self._has_th.append(th)
        # 执行创建线程时分配的任务
        func, *args = args
        func(*args)
        # 线程阻塞,进入等待任务队列
        while True:
            self._pending.put(1)
            try:
                # 获取任务
                task, *arg = self._task.get(timeout=1)
            except Empty:
                self._pending.get()
                return
            # 从等待队列取出并执行任务
            self._pending.get()
            task(arg)

    def submit(self, func, args):
        # 线程池关闭
        if self._close:
            raise RuntimeError("thread closed")
        # 当无空闲线程且当前线程数小于最大可运行线程数,创建新的线程。
        elif self._pending.empty() and len(self._has_th) < self.max_workers:
            th = Thread(target=self.worker, args=(func, args))
            # th.setDaemon(True) # 主进程结束是否结束子进程 默认False
            th.start()
        else:
            try:
                # 当所有线程都在运行,且线程数达到最大值,任务进入等待队列
                self._task.put((func, args), block=True, timeout=25)
            except Full:
                # 等待进入队列超时
                raise TimeoutError("任务提交超时")

    def close(self):
        self._close = True


# 鉴权
class get_result(object):
    def __init__(self, host):
        # 应用ID(到控制台获取)
        self.APPID = APPId
        # 接口APISercet(到控制台机器翻译服务页面获取)
        self.Secret = APISecret
        # 接口APIKey(到控制台机器翻译服务页面获取)
        self.APIKey = APIKey

        # 以下为POST请求
        self.Host = host
        self.RequestUri = "/v2/ots"
        # 设置url
        # print(host)
        self.url = "https://" + host + self.RequestUri
        self.HttpMethod = "POST"
        self.Algorithm = "hmac-sha256"
        self.HttpProto = "HTTP/1.1"

        # 设置当前时间
        curTime_utc = datetime.datetime.utcnow()
        self.Date = self.httpdate(curTime_utc)
        # 设置业务参数
        # 语种列表参数值请参照接口文档:https://www.xfyun.cn/doc/nlp/niutrans/API.html
        self.BusinessArgs = {
            "from": "en",
            "to": "cn",
        }

    def hashlib_256(self, res):
        m = hashlib.sha256(bytes(res.encode(encoding='utf-8'))).digest()
        result = "SHA-256=" + base64.b64encode(m).decode(encoding='utf-8')
        return result

    def httpdate(self, dt):
        """
        Return a string representation of a date according to RFC 1123
        (HTTP/1.1).

        The supplied date must be in UTC.

        """
        weekday = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][dt.weekday()]
        month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
                 "Oct", "Nov", "Dec"][dt.month - 1]
        return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (weekday, dt.day, month,
                                                        dt.year, dt.hour, dt.minute, dt.second)

    def generateSignature(self, digest):
        signatureStr = "host: " + self.Host + "\n"
        signatureStr += "date: " + self.Date + "\n"
        signatureStr += self.HttpMethod + " " + self.RequestUri \
                        + " " + self.HttpProto + "\n"
        signatureStr += "digest: " + digest
        signature = hmac.new(bytes(self.Secret.encode(encoding='utf-8')),
                             bytes(signatureStr.encode(encoding='utf-8')),
                             digestmod=hashlib.sha256).digest()
        result = base64.b64encode(signature)
        return result.decode(encoding='utf-8')

    def init_header(self, data):
        digest = self.hashlib_256(data)
        # print(digest)
        sign = self.generateSignature(digest)
        authHeader = 'api_key="%s", algorithm="%s", ' \
                     'headers="host date request-line digest", ' \
                     'signature="%s"' \
                     % (self.APIKey, self.Algorithm, sign)
        # print(authHeader)
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json",
            "Method": "POST",
            "Host": self.Host,
            "Date": self.Date,
            "Digest": digest,
            "Authorization": authHeader
        }
        return headers

    def get_body(self, text):
        content = str(base64.b64encode(text.encode('utf-8')), 'utf-8')
        postdata = {
            "common": {"app_id": self.APPID},
            "business": self.BusinessArgs,
            "data": {
                "text": content,
            }
        }
        body = json.dumps(postdata)
        # print(body)
        return body

    def call_url(self, text):
        if self.APPID == '' or self.APIKey == '' or self.Secret == '':
            print('Appid 或APIKey 或APISecret 为空!请打开demo代码,填写相关信息。')
        else:
            code = 0
            body = self.get_body(text)
            headers = self.init_header(body)
            # print(self.url)
            response = requests.post(self.url, data=body, headers=headers, timeout=8)
            status_code = response.status_code
            # print(response.content)
            if status_code != 200:
                # 鉴权失败
                print("Http请求失败,状态码:" + str(status_code) + ",错误信息:" + response.text)
                print("请根据错误信息检查代码,接口文档:https://www.xfyun.cn/doc/nlp/niutrans/API.html")
                return None
            else:
                # 鉴权成功
                respData = json.loads(response.text)
                # print(respData)
                # 以下仅用于调试
                code = str(respData["code"])
                if code != '0':
                    print("请前往https://www.xfyun.cn/document/error-code?code=" + code + "查询解决办法")
                else:
                    return respData["data"]["result"]["trans_result"]["dst"]

            return None


def ai_translate(text):
    if text.isspace():
        print("the data is null")
        return
    ret = get_result(HOST).call_url(text)
    print(ret)
    return ret


def split_form(parm_form):
    print("split_form: ")
    try:
        for row in parm_form.rows:  # 从表格第一行开始循环读取表格数据
            for cell in row.cells:  # 遍历每一个单元格
                for j in range(len(row.cells)):
                    if ("\n" != row.cells[j].text) & ("\r" != row.cells[j].text) & (0 != len(row.cells[j].text)) & \
                            ("\r\n" != row.cells[j].text) & (not row.cells[j].text.isspace()):
                        row.cells[j].text = ai_translate(row.cells[j].text)
                        print(row.cells[j].text)
    except AttributeError as e:
        print("parm has no rows")


def split_paragraph_runs(parm_paragraph):
    print("split_paragraph_runs: ")
    try:
        runs = parm_paragraph.runs
        for i, run in enumerate(runs):
            if run.text:
                if ("\n" != run.text) & ("\r" != run.text) & (0 != len(run.text)) & ("\r\n" != run.text) & (
                        not run.text.isspace()):
                    run.text = ai_translate(run.text)
    except AttributeError as e:
        print("parm has no text")


if __name__ == '__main__':
    thread_pool = ThreadPoolExecutor(max_workers=6)
    start_time = datetime.datetime.now()
    doc = Document('../source/src1.docx')  # exist.docx为文件名
    # 表格内容翻译
    tables = doc.tables  # 获取文件中的表格集
    print("表格数量:", len(tables))  # 获取文件中的表格数量
    for table in tables:  # 遍历每一个表格
        thread_pool.submit(split_form, table)

    # 文本内容翻译
    for paragraph in doc.paragraphs:
        if ("\n" != paragraph.text) & ("\r" != paragraph.text) & (0 != len(paragraph.text)) & (
                "\r\n" != paragraph.text) & (not paragraph.text.isspace()):
            thread_pool.submit(split_paragraph_runs, paragraph)
    thread_pool.shutdown(wait=True)
    doc.save('../source/dst.docx')

    end_time = datetime.datetime.now()
    print("cost total time:", (end_time - start_time).seconds)
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1341070.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AOT编程

1. AOT与JIT AOT&#xff1a;Ahead-of-Time&#xff08;提前编译&#xff09;&#xff1a;程序执行前&#xff0c;全部被编译成机器码 JIT&#xff1a;Just in Time&#xff08;即时编译&#xff09;: 程序边编译&#xff0c;边运行&#xff1b; 编译&#xff1a; 源代码&a…

oled显示汉字字体 形状 使用

oled模块的工作原理 oled的上方四个接口是IIC总线 通过IIC总线可以进行数据的传输 在OLED模块背后有一个芯片叫做SSD1306 这个芯片内部有1024个字节的RAM 对应到右边的小屏幕上就有1024个字节 一个字节八个bit位 每一个bit位就对应着一个小点 我们只需要往oled的RAM上写入数据就…

TPRI-DMP平台介绍

TPRI-DMP平台介绍 TPRI-DMP平台概述 TPRI-DMP为华能集团西安热工院自主产权的工业云PaaS平台&#xff0c;已经过13年的发展和迭代&#xff0c;其具备大规模能源电力行业生产应用软件开发和运行能力。提供TPRI-DMP平台主数据管理、业务系统开发与运行、应用资源管理与运维监控…

新能源光伏行业CRM:推动绿色能源发展与高效客户管理的双重突破

随着“碳中和”计划以及传统能源价格的不断飙升&#xff0c;我国新能源光伏产业在国家“双碳”战略目标和市场需求的双重驱动下高歌猛进&#xff0c;中国光伏产业新增装机量、累计装机量连续多年位居全球首位。CRM在光伏产业中的作用也日益突出。下面为您介绍新能源光伏行业的C…

UDP单播

CMakeLists.txt文件中添加如下行&#xff1a; link_libraries(ws2_32) 1.发送端 #include <iostream> #include <winsock2.h> #include <cstdio>#pragma comment(lib, "Ws2_32.lib") // Link with ws2_32.libint main() {1.Initialize winsock…

Redis中RDB和AOF

Redis中RDB和AOF 定时间间隔执行数据集的时间快照&#xff0c;把某一时刻数据和妆容以文件的形式写到磁盘上&#xff0c;也就是快照。 配置文件 如果是普通安装方式可以跳过&#xff0c;如果是docker安装&#xff0c;需要到官网下载redis.conf配置文件到本地&#xff0c;地址…

配置IPv6静态路由示例

1、静态路由简介 静态路由是一种需要管理员手工配置的特殊路由。 静态路由在不同网络环境中有不同的目的&#xff1a; 当网络结构比较简单时&#xff0c;只需配置静态路由就可以使网络正常工作。 在复杂网络环境中&#xff0c;配置静态路由可以改进网络的性能&#xff0c;并…

嵌入式开发——ADC模拟信号和数字信号

模拟信号和数字信号 模拟信号 自然界中大多数物理量是连续变化的,比如温度、声音、压力等灯,它们在一定时间内,可以有无限多个不同的取值,这些信号就是模拟信号。模拟信号就是指用连续变化的物理量所表示的信号。 自然界中的物理量都需要通过传感器将其转换成电信号后,才能进…

锐捷路由小型综合实验

一、实验拓扑 二、实验目的 1、熟练掌握ospf的配置 2、熟练掌握RIP的配置 3、熟练掌握静态路由的配置 4、熟练掌握各种路由协议之间的引入 5、熟练掌握telnet和ssh的配置 三、实验配置 R1 //配置telent username admin password admin123 enable password admin123 enable…

java设计模式学习之【迭代器模式】

文章目录 引言迭代器模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用迭代器示例代码地址 引言 想象一下&#xff0c;你在一个书店里浏览各种书籍。你可能会从头到尾查看每一本书&#xff0c;或者可能跳过一些不感兴趣的部分。在这个过程中&#xff0c;你实…

Yapi接口管理平台Centos7部署

文章目录 1.环境准备1.1 关闭透明大页THP1.2 设置最大文件打开数最大进程数 2.Nodejs安装3.安装Mongodb3.1 下载安装3.2 配置3.3 配置环境变量3.4 启动3.5 关闭 4.安装YAPI4.1 离线安装4.2 页面安装&#xff08;本次采用&#xff09;4.3 访问 1.环境准备 1.1 关闭透明大页THP …

c语言:输出范围内的质数|练习题

一、题目 输入一个数n&#xff0c;输出n之内的所有质数 如图&#xff1a; 二、思路分析 1、设置一个数num&#xff0c;从2开始&#xff0c;不断作1操作&#xff0c;作为被除数 2、用一个不断自1的数&#xff0c;除以num&#xff0c;如果num不能被整除&#xff0c;则为质数 3、例…

Google Ad帐号被封?这几个关键点看好

海外广告投放工作中&#xff0c;账号是非常重要的环节。与在Facebook上运行广告相比&#xff0c;运行Google Ads在代理选择方面通常没有那么严格&#xff0c;因为 Google 对 IP 使用并不那么严格。但是&#xff0c;这并不意味着您可以不加考虑地使用任何代理IP。在本文中&#…

MySQL事务、四大原则、执行步骤、四种隔离级别、锁、脏读、脏写等

MySQL事务 MySQL事务1.什么是事务&#xff1f;2.事务的四大原则3.事务执行的步骤4、事务的隔离性5、MySQL中的锁 MySQL事务 模拟一个转账业务&#xff1a; 上图中的sql语句&#xff1a; update from table set money mongey - 100 where name A; update from table set mone…

【数据结构】插入排序、选择排序、冒泡排序、希尔排序、堆排序

前言&#xff1a;生活中我们总是会碰到各种各样的排序&#xff0c;今天我们就对部分常用的排序进行总结和学习&#xff0c;今天的内容还是相对比较简单的一部分&#xff0c;各位一起加油哦&#xff01; &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f44…

Python经典游戏 唤醒你童年记忆

这些游戏你玩过几个&#xff1f; 1.贪吃蛇2.吃豆人3.加农炮4.四子棋5. Fly Bird<font color #f3704ab>6.记忆&#xff1a;数字对拼图游戏&#xff08;欢迎挑战&#xff01;用时&#xff1a;2min&#xff09;7.乒乓球8.上课划水必备-井字游戏&#xff08;我敢说100%的人都…

verilog rs232串口模块

前面发了个发送模块&#xff0c;这次补齐&#xff0c;完整。 串口计数器&#xff0c;波特率适配 uart_clk.v module uart_clk(input wire clk,input wire rst_n,input wire tx_clk_en,input wire rx_clk_en,input wire[1:0] baud_sel,output wire tx_clk,output wire rx_clk )…

spring、springmvc、springboot、springcloud简介

spring简介 spring是什么&#xff1f; spring: 春天spring: 轻量级的控制反转和面向切面编程的框架 历史 2002年&#xff0c;首次推出spring雏形&#xff0c;interface 21框架2004年&#xff0c;发布1.0版本Rod Johnson: 创始人&#xff0c;悉尼大学&#xff0c;音乐学博士…

什么是 NLP (自然语言处理)

NLP&#xff08;自然语言处理&#xff09;到底是做什么&#xff1f; NLP 的全称是 Natural Language Processing&#xff0c;翻译成中文称作&#xff1a;自然语言处理。它是计算机和人工智能的一个重要领域。顾名思义&#xff0c;该领域研究如何处理自然语言。 自然语言就是我…

企业如何购买腾讯云服务器?(详细指南)

腾讯云服务器购买流程直接在官方秒杀活动上购买比较划算&#xff0c;在云服务器CVM或轻量应用服务器页面自定义购买价格比较贵&#xff0c;但是自定义购买云服务器CPU内存带宽配置选择范围广&#xff0c;活动上购买只能选择固定的活动机&#xff0c;选择范围窄&#xff0c;但是…