go实现英译汉词典|青训营笔记

147 阅读3分钟
这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

效果演示

image.png

翻译API选择

由于视频课里面使用的是彩云小译,这里我就换一个翻译接口进行尝试
这里我选择的是我爱翻译 - 在线翻译 (woaifanyi.com)
其实也考虑过主流的翻译引擎比如有道翻译,腾讯翻译等,但请求和响应都有被加密或者返回的json过于庞大,且js逆向过于麻烦,故此选择我爱翻译来进行演示

API接口解析

  • 打开我爱翻译,按F12进入开发者面板(或者按鼠标右键->检查此页面)
  • 打开网络的Tab(如果没有点击右边+号或者>>进行查找)
  • 接下来我们按下图中的操作顺序进行单词翻译接口的查找

image.png 可以看到只有一条请求

image.png 解析后可以看到返回的json中就有我们需要的翻译结果
接下来我们需要使用golang去发送请求并进行解析

Golang 请求生成

  • 右键该请求
  • 复制
  • 复制为cURL(bash)

image.png 接下来打开这个网站Convert curl commands to Go (curlconverter.com)
将复制的curl粘贴进去,然后使用生成的go代码创建一个go项目

image.png

由于返回的是一个json,所以我们需要创建一个结构体来对响应进行解析

image.png

type AutoGenerated []struct {
	XSWZ int `json:"x_s_w_z"`
	NR string `json:"n_r"`//根据上面的unicode解析可以看到这个字段为翻译结果
}

完善请求函数 输出结果

func query(word string) {
   client := &http.Client{}

   var data = strings.NewReader("source=" + word + "&from=1&to=2")//构造请求的参数
   req, err := http.NewRequest("POST", "https://www.woaifanyi.com/api/2.0/save/?ajaxtimestamp=1673792987537", data)
   if err != nil {
      log.Fatal(err)
   }
   req.Header.Set("authority", "www.woaifanyi.com")
   req.Header.Set("accept", "*/*")
   req.Header.Set("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
   req.Header.Set("content-type", "application/x-www-form-urlencoded")
   req.Header.Set("cookie", "Hm_lvt_5899173c4bb390c78c9ffd1e2846117d=1673792892; Hm_lpvt_5899173c4bb390c78c9ffd1e2846117d=1673792892")
   req.Header.Set("origin", "https://www.woaifanyi.com")
   req.Header.Set("referer", "https://www.woaifanyi.com/")
   req.Header.Set("sec-ch-ua", `"Not?A_Brand";v="8", "Chromium";v="108", "Microsoft Edge";v="108"`)
   req.Header.Set("sec-ch-ua-mobile", "?1")
   req.Header.Set("sec-ch-ua-platform", `"Android"`)
   req.Header.Set("sec-fetch-dest", "empty")
   req.Header.Set("sec-fetch-mode", "cors")
   req.Header.Set("sec-fetch-site", "same-origin")
   req.Header.Set("user-agent", "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Mobile Safari/537.36 Edg/108.0.1462.76")
   resp, err := client.Do(req)
   if err != nil {
      log.Fatal(err)
   }
   defer resp.Body.Close()
   bodyText, err := ioutil.ReadAll(resp.Body)
   if err != nil {
      log.Fatal(err)
   }
   if resp.StatusCode != 200 {
      log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))
   }

   var dictResponse DictResponse
   err = json.Unmarshal(bodyText, &dictResponse)//对响应进行反序列化
   if err != nil {
      log.Fatal(err)
   }
   fmt.Println(dictResponse[0].NR)//我们输出其中一个结果即可,其实这里还少了判空
}

简单判断输入是否为英文

func ContainsEnglish(str string) bool {
   dictionary := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
   for _, v := range str {
      if strings.Contains(dictionary, string(v)) {
         return true
      }
   }
   return false
}

主函数

func main() {
   for {
      input := ""
      fmt.Scanf("%s\n", &input)
      if ContainsEnglish(input) {
         query(input)
      } else {
         fmt.Println("input error!!! please input English!!!")
      }
   }
}

至此,我们的go翻译字典就已经写完了,如果有什么疑问,或者问题欢迎在评论区进行讨论。