Golang实现在线词典--实践选题 | 青训营

99 阅读3分钟

这篇文章使用go语言调用相关翻译平台的API,实现go语言版本的在线翻译。

一、我们通过浏览器开发者工具中的network,查看请求为post的dict,从而获得该api的url

image.png

二、复制下图所示的curl,获得请求的相关请求头信息。我们通过在线转换工具curlconverter.com/ ,将请求头的信息快捷转换到go代码中,我们将这串代码作为程序的主体部分,接下来修改这段程序

image.png

三、我们查看请求头里面携带的字段,这里上传的数据有 转换类型以及翻译的数据

image.png

所以我们创建这样的结构体用于携带数据

type DictRequest struct {  
    //后面的表示结构体对应到json中的字段名
    TransType string `json:"trans_type"`  
    Source string `json:"source"`  
}

四、接下来我们还需要获取响应体中携带的数据,我们查看preview里面的数据,这里就是响应返回的数据

image.png

这样的响应数据同样需要结构体相对应,我们借助在线转换工具oktools.net/json2go 转换json结构为结构体,作用于代码中json数据反序列化后存储数据,得到这样的结构体

type AutoGenerated struct {  
    Rc int `json:"rc"`  
    Wiki struct {  } `json:"wiki"`  
    Dictionary struct {  
        Prons struct {  
            EnUs string `json:"en-us"`  
            En string `json:"en"`  
        } `json:"prons"`  
        Explanations []string `json:"explanations"`  
        Synonym []string `json:"synonym"`  
        Antonym []string `json:"antonym"`  
        WqxExample [][]string `json:"wqx_example"`  
        Entry string `json:"entry"`  
        Type string `json:"type"`  
        Related []interface{} `json:"related"`  
        Source string `json:"source"`  
    } `json:"dictionary"`  
}

五、上述工作完成后,准备工作已经完成了,接下来我们修改代码以完成在线词典。

在Go语言中,可以使用&http.Client{}来创建一个HTTP客户端。http.Client{}是一个结构体类型,用于发送HTTP请求并处理响应。

//创建http请求,可以设置超时等信息  
client := &http.Client{}  

该结构体用于设置请求头中传递的数据。我们这里设置转换类型为英文转中文,转换的单词为word变量中存储的数据

//创建一个结构体并初始化  
request := DictRequest{  
    TransType: "en2zh",  
    Source: word,  
}  

网页中的数据传输为json数据,我们序列化结构体为json方便数据传输

//序列化为json  
buf, err := json.Marshal(request)  
//排错误
if err != nil {  
log.Fatal(err)  
}  
//转化数据成流的形式,由于json.Marshal返回的是byte数组,所以使用bytes.NewReader。下面的方式也可以  
var data = bytes.NewReader(buf)  
//data := strings.NewReader(string(buf))  

向后端传递数据,创建post请求

//创建post请求,这里最后一个是数据,以流的方式传入,这样节省内存  
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)  
if err != nil {  
log.Fatal(err)  
}  
//设置请求头  
req.Header.Set("authority", "api.interpreter.caiyunai.com")  
req.Header.Set("sec-ch-ua", `" Not A;Brand";v="99", "Chromium";v="8"`)  
req.Header.Set("sec-ch-ua-mobile", "?0")  
req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.1.4031 SLBChan/103")  
req.Header.Set("app-name", "xy")  
req.Header.Set("content-type", "application/json;charset=UTF-8")  
req.Header.Set("accept", "application/json, text/plain, */*")  
req.Header.Set("device-id", "fe0083831852ea22f8c6c40e78633937")  
req.Header.Set("os-type", "web")  
req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")  
req.Header.Set("origin", "https://fanyi.caiyunapp.com")  
req.Header.Set("sec-fetch-site", "cross-site")  
req.Header.Set("sec-fetch-mode", "cors")  
req.Header.Set("sec-fetch-dest", "empty")  
req.Header.Set("referer", "https://fanyi.caiyunapp.com/")  
req.Header.Set("accept-language", "zh-CN,zh;q=0.9")  

发起请求

//真正发起请求  
resp, err := client.Do(req)  
if err != nil {  
    //请求失败退出进程  
    log.Fatal(err)  
}

下面处理响应

//请求成功后,返回的resp.Body也是一个流,需要关闭这个流  
//defer会在函数结束之后从下往上关闭  
defer resp.Body.Close()  
//把流读出来到byte数组中  
bodyText, err := io.ReadAll(resp.Body)  
if err != nil {  
    log.Fatal(err)  
}  
//判断请求是否成功  
if resp.StatusCode != 200 {  
    //输出错误结果,退出程序  
    log.Fatal("bad StatusCode:", resp.StatusCode, "body:", string(bodyText))  
}  

通过io流获得的数据为JSON格式,反序列化到结构体中

//开始反序列化  
var autoGenerated AutoGenerated  
err = json.Unmarshal(bodyText, &autoGenerated)  
if err != nil {  
    log.Fatal(err)  
}  

下面三个字段就是结构体中对应着的 单词,音标,释义,我们从开发者工具返回的响应数据便可以轻松猜到每个字段对应的内容

fmt.Println("Word:", word, "UK:", autoGenerated.Dictionary.Prons.En, "US:", autoGenerated.Dictionary.Prons.EnUs)  
for _, item := range autoGenerated.Dictionary.Explanations {  
`fmt.Println(item)  
}

至此,我们已经基本实现目标了。

image.png