[用go语言实现在线词典|青训营笔记]
这是我参与[第五届青训营]笔记创作活动的第1天。这里实现一下课程中的实战案例2:在线词典
实现效果
实现的原理即为调用第三方的翻译api。进入fanyi.caiyunapp.com/网站后,随便输入一个单词点击“翻译”,即为请求;显示释译结果,即为响应。
实现过程
刚刚是在网站上进行翻译,现在我们要把翻译“搬”到自己的编译器或者命令行中。这里可以用一个工具(https://curlconverter.com/go/),它可以根据curl请求,直接生成访问api,实现相关服务的代码。
curl:用来请求 Web 服务器的工具,它的名字就是客户端(client)的 URL 工具的意思
1.复制工具生成的代码
打开检查面板,找到检查面板中名为dict的POST请求并复制其curl
再粘贴到工具命令行中,选择go语言,可以看到面板直接生成了实现翻译服务的代码👇。
2.修改代码
对生成的代码做出以下修改,创建了请求信息的结构体,同时实现了请求信息的类型转换,后面马上就会讲做出的修改具体是什么意思
刚刚我们修改的内容实现了翻译信息结构体的序列化
调用json.marshal(变量),即把变量中的数据序列化
可以理解为,把存储翻译信息的变量序列化为byte数组,以方便数据传输
既然把变量数据传输上去需要进行序列化,那传输回来的数据要储存到本地就要进行反序列化。
3.创建响应结构体
之前已经写了请求结构体,我们再来创建一个响应结构体来作本地变量,用来存储翻译结果,这里我们又可以运用工具<JSON转Golang Struct - 在线工具 - OKTools>,我们先复制浏览器页面响应翻译的json内容👇
再输入到json栏中,选择嵌套转换
可以看到工具又帮我们生成了go语言的结构体,自行复制进工程即可。
4.反序列化
自行创建一个刚刚生成的结构体变量,把json翻译结果的byte数组反序列化,再储存结果信息到变量中。最后输出即可
完整代码
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
type DictRequest struct { //请求结构体
TransType string `json:"trans_type"`
Source string `json:"source"`
UserID string `json:"user_id"`
}
type DictResponse struct { //响应结构体
Rc int `json:"rc"`
Wiki struct {
KnownInLaguages int `json:"known_in_laguages"`
Description struct {
Source string `json:"source"`
Target interface{} `json:"target"`
} `json:"description"`
ID string `json:"id"`
Item struct {
Source string `json:"source"`
Target string `json:"target"`
} `json:"item"`
ImageURL string `json:"image_url"`
IsSubject string `json:"is_subject"`
Sitelink string `json:"sitelink"`
} `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"`
}
func query(word string) {
client := &http.Client{}
request := DictRequest{TransType: "en2zh", Source: word} //创建自定义的请求结构体
buf, err := json.Marshal(request)//序列化结构体,转型为byte数组
if err != nil {
log.Fatal(err)
}
var data = bytes.NewReader(buf)//将byte数组转换为流
req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data) //创建请求,参数为请求方法、url、流
if err != nil {
log.Fatal(err)
}
req.Header.Set("Connection", "keep-alive")
req.Header.Set("DNT", "1")
req.Header.Set("os-version", "")
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36")
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", "")
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")
req.Header.Set("Cookie", "_ym_uid=16456948721020430059; _ym_d=1645694872")
resp, err := client.Do(req) //发请求
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close() //关闭流
bodyText, err := ioutil.ReadAll(resp.Body) //把该流,类型转换为byte数组,此byte数组内容为JSON字符串
if err != nil {
log.Fatal(err)
}
//---------------------------------------------------------↑工具生成的代码,自行添加请求结构体,并序列化
var dictResponse DictResponse //创建响应结构体变量
err = json.Unmarshal(bodyText, &dictResponse) //反序列化,将json中的数据写入结构体
if err != nil {
log.Fatal(err)
}
//只输出需要的东西,需要的东西可以在 浏览器的响应预览中查看字段
pronsUS := dictResponse.Dictionary.Prons.EnUs
pronsEn := dictResponse.Dictionary.Prons.En
if len(pronsEn) == 0 {
println("没有查找到该单词哦T-T")
return
}
fmt.Println(word, "---------", "UK:", pronsEn, "US:", pronsUS) //输出英/美音标
for _, item := range dictResponse.Dictionary.Explanations {
fmt.Println(item)
} //循环输出中文释意
}
func main() {
print("请输入一个单词:")
var word string
fmt.Scanln(&word)
query(word)
}
思考:什么是序列化,为什么要序列化?
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据, 要想将对象传输于网络必须进行流化!在对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的
新人小白,完成作业,有哪里写的不对的地方还请指出!!一起学习