这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记
在线词典功能介绍
在调用程序时只需要在后面填入单词,就会显示单词的意思
原理是调用第三方的API查询单词的翻译,并且将查询结果打印出来
这里我调用的是火山翻译,因为火山翻译返回结果是简单的Json格式,不需要进行一些复杂的变换
程序运行实例图如下:
程序实现过程
1、抓包、解析网站发送的数据格式
我们打开火山翻译界面,打开浏览器控制台监控网络传输情况
任意输入一个单词,找到我们需要的返回文件数据
能看到如上图手势指向的文件就是发送的请求
可以看到请求的数据和配置很多,如果要自己完成可能非常麻烦
我们可以使用 curlconverter.com/#go 提供的实现自动的生成相关代码功能
右键该文件,选择复制为cURL
将复制结果粘贴到 curlconverter.com/#go 中,就能够自动生成相关代码了
2、解析返回的JSON数据
得到代码后,我们来分析一下代码的内容
来尝试运行一下看看能输出什么内容
可以看到输出了一大串的JSON,我们需要的结果就在JSON里
为了简单起见,这里只提取该单词的翻译。其中的例句之类的信息直接丢弃
我们要反序列化结果的JSON,可以使用 oktools.net/json2go 提供的工具生成JSON的结构代码
复制输出的结果,除去一些换行等信息。
因为我们不需要对返回结果进行过多的操作,使用“转换-嵌套”,可以使得代码更为紧凑
接下来我们修改一些代码,将JSON数据反序列化到变量中
AutoGenerated就是上面得到的JSON的格式化代码。可以使用“%#v”输出结构体变量的详细信息
我们可以得到一长串的信息,但是我们不需要这么多信息,只需要翻译的内容
结合输出结果和结构体代码,我们可以找到翻译结果的存储位置:
所以我们只需要输出AutoGenerated下的Words下的PosList下的Explanations下的Text就可(可能有点长
所以再次修改我们的代码:
我们就能得到需要的输出了
3、设置命令行输入单词翻译
我们发现现在需要翻译其他单词只能修改源代码,这显然没有做到一个程序员应该做到的交互操作
我们可以将原main函数中的代码封装为一个函数,函数设置word参数,实现从命令行输入单词传入函数得到翻译结果
完成这两步我们的程序就算成功了
最后我们的功能展示如下
4、最终代码
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
)
type AutoGenerated struct {
Words []struct {
Source int `json:"source"`
Text string `json:"text"`
PosList []struct {
Type int `json:"type"`
Phonetics []struct {
Type int `json:"type"`
Text string `json:"text"`
} `json:"phonetics"`
Explanations []struct {
Text string `json:"text"`
Examples []struct {
Type int `json:"type"`
Sentences []struct {
Text string `json:"text"`
TransText string `json:"trans_text"`
} `json:"sentences"`
} `json:"examples"`
Synonyms []interface{} `json:"synonyms"`
} `json:"explanations"`
Relevancys []interface{} `json:"relevancys"`
} `json:"pos_list"`
} `json:"words"`
Phrases []interface{} `json:"phrases"`
BaseResp struct {
StatusCode int `json:"status_code"`
StatusMessage string `json:"status_message"`
} `json:"base_resp"`
}
func HuoShan(word string) {
client := &http.Client{}
var data = strings.NewReader(`{"text":"` + word + `","language":"en"}`)
req, err := http.NewRequest("POST", "https://translate.volcengine.com/web/dict/match/v1/?msToken=&X-Bogus=DFSzswVLQDc7Eu3KSWH2qsUClLxa&_signature=_02B4Z6wo00001FnkuZAAAIDBcm7iVysoh5BZ5L0AAHQHcz130TjK8x7CNsIS6vQ3Lj2smHucJ9SY6YcbE9BvRlUhX2nU9vWWanBFiKBRb5hyOGW8usVR0hQ9LFhYX9eu87Z5Q.JUqqwnKb1f12", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("authority", "translate.volcengine.com")
req.Header.Set("accept", "application/json, text/plain, */*")
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("cache-control", "no-cache")
req.Header.Set("content-type", "application/json")
req.Header.Set("cookie", "x-jupiter-uuid=16518491619698024; i18next=zh-CN; ttcid=edaf3b3b984140d884d5c8b7e75d023d29; s_v_web_id=verify_7803fc0105a7bd23f690d645be06e37e; _tea_utm_cache_2018=undefined; tt_scid=P2mPJqgyrhzfyPg79xGj36hfHCIbkYY0l5uc865DMdrjTrbwbQjNAX7xiEUJD5vh9722")
req.Header.Set("origin", "https://translate.volcengine.com")
req.Header.Set("pragma", "no-cache")
req.Header.Set("referer", "https://translate.volcengine.com/translate?category=&home_language=zh&source_language=detect&target_language=zh&text=good")
req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="101", "Microsoft Edge";v="101"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"Windows"`)
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 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36 Edg/101.0.1210.39")
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)
}
// fmt.Printf("%s\n", bodyText)
var autoGenerated AutoGenerated
err = json.Unmarshal(bodyText, &autoGenerated)
if err != nil {
log.Fatal(err)
}
// fmt.Printf("%#v", autoGenerated)
fmt.Println(autoGenerated.Words[0].PosList[0].Explanations[0].Text)
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, `usage: simpleDict WORD
example: simpleDict hello
`)
os.Exit(1)
}
word := os.Args[1]
HuoShan(word)
}