基于Golang的命令行翻译工具_集成谷歌翻译API

2次阅读

正确路径是使用 google Cloud 官方 Cloud Translation API v3,需配置 Service Account + OAuth2 认证,用 cloud.google.com/go/translate/apiv3 SDK 调用,语言代码须为 BCP-47 格式(如”zh”),Contents 批量上限 128 条且总字符≤30K,本地测试可用 httptest.Server 模拟响应。

基于Golang的命令行翻译工具_集成谷歌翻译API

golang 调用谷歌翻译 API 遇到 403 Forbidden400 Bad Request

谷歌官方已关闭免费的 translate.google.com Web 接口,直接 HTTP GET 解析 HTML 会立即触发反爬,返回 403;而旧版非官方 API(如 https://translate.googleapis.com/translate_a/single)虽偶能用,但无认证、不稳定、随时失效,且参数稍错就 400

正确路径是使用 Google Cloud 官方 Cloud Translation API v3,必须配 Service Account + OAuth2 认证,走 REST 或 client library。

  • 先去 Google Cloud Console 启用 Cloud Translation API
  • 创建 Service Account,下载 json 密钥文件(如 creds.json),设环境变量:export GOOGLE_APPLICATION_CREDENTIALS="./creds.json"
  • Go 里用官方 SDK:cloud.google.com/go/translate/apiv3,别手写 HTTP 请求

cloud.google.com/go/translate/apiv3 实现基础翻译

SDK 封装了认证和重试逻辑,比裸调 REST 稳定得多。注意它默认用 gRPC,若内网或代理环境不通,可强制切 HTTP/1.1。

关键点:语言代码必须是 BCP-47 格式(如 "zh""en""ja"),不是 "zh-CN" 这类带区域的——后者会被静默忽略或报错。

立即学习go语言免费学习笔记(深入)”;

import (     "context"     "log"     t "cloud.google.com/go/translate/apiv3"     "google.golang.org/api/option" ) <p>func translateText(ctx context.Context, text, src, tgt string) (string, error) { client, err := t.NewTranslationClient(ctx, option.WithEndpoint("<a href="https://www.php.cn/link/cd8b6b3c5d37cd78b6de2c4b5e80b15d">https://www.php.cn/link/cd8b6b3c5d37cd78b6de2c4b5e80b15d</a>")) if err != nil { return "", err } defer client.Close()</p><pre class="brush:php;toolbar:false;">req := &tpb.TranslateTextRequest{     Parent:      "projects/YOUR_PROJECT_ID",     Contents:    []string{text},     SourceLanguageCode: src,     TargetLanguageCode: tgt, } resp, err := client.TranslateText(ctx, req) if err != nil {     return "", err } return resp.GetTranslations()[0].GetTranslatedText(), nil

}

命令行参数解析与批量翻译性能控制

用户常想一次翻多句,但 TranslateTextContents 字段最多支持 128 条,且总字符数不能超 30K。硬塞超限会直接 413 Payload Too Large

命令行工具要自己做分批:按字符数切,不是按行数切;每批间隔加 time.Sleep(50 * time.Millisecond) 防被限流。

  • flag 包解析 -src-tgt-f(文件路径)比手动 os.Args 更健壮
  • 读文件时用 bufio.Scanner,别 ioutil.ReadFile 全载入内存——大文件直接 OOM
  • 输出格式建议纯文本,默认不加 JSON 或颜色,避免管道消费出错(比如 cat input.txt | ./trans -tgt ja

本地测试时如何绕过网络和配额限制

开发阶段频繁跑 CI 或本地调试,不想每次调真实 API,也怕耗光免费额度(每月前 50 万字符免费,但计费从第 1 字符开始)。

最简方案:用 Go 的 httptest.Server 模拟响应,再把 client 的 endpoint 指向它。不要 mock 整个 client —— 太重,且容易漏掉 auth header 或 URL path 细节。

示例片段:

srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {     w.Header().Set("Content-Type", "application/json")     w.WriteHeader(200)     w.Write([]byte(`{"translations":[{"translatedText":"你好世界"}]}`)) })) defer srv.Close() <p>// 创建 client 时传入自定义 endpoint: client, _ := t.NewTranslationClient(ctx, option.WithEndpoint(srv.URL+":443"))</p>

注意:mock 的 endpoint 必须带端口(即使 :443),否则 SDK 会 fallback 到默认地址。

真实项目里,把翻译逻辑抽成 Interface,测试时注入 mock impl,比 patch endpoint 更干净——但命令行小工具没必要,够用就行。

text=ZqhQzanResources