这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。
字节跳动青训营开课第1天!期待已久的青训营课程今天终于开始啦。今天的课程为我们讲解了go语言的基础语法,并给出了三个十分有趣的小demo,命令行字典便是其中之一。
网课github仓库提供了demo的源码,运行效果如上图。源码中用到了彩云翻译引擎的接口,基本实现了英文单词翻译的基础功能,十分别致!直播课中也详细的讲解了这个字典的实现过程和思路。
课程结束后,讲师为我们布置了对应的作业——为命令行字典添加另一个翻译引擎! 那我也参照直播课中的思路来做一下吧。
抓取接口
首先选择一个翻译引擎,这里我使用百度翻译。打开百度翻译页面,随便输入一个单词:
如所期望的看到了单词的具体翻译。然后打开开发者工具,再次点击翻译按钮:
观察network情况,发现一时间内出现了大量的请求,其中一条名为v2transapi的请求响应里刚好包含了我们想要的翻译信息。
然鹅,经过尝试,很遗憾的发现这个接口很难拿来用啦,原因是其负载的表单数据中有一个sign字段不知道是怎么得来的。在无法给出正确的sign值的情况下请求都失败了......
好在经过一番观察,我很快找到了另一个名为sug的请求,其响应也给出了我们所需的翻译信息!(虽然没有音标),其参数只需要一个要翻译的英文单词即可,十分简洁。
生成代码
确定了要使用的接口,我们便复制请求对应的curl:
然后打开直播课中提到的网站:curlconverter.com,在其中生成向该接口发送请求的Go语言代码。
取得到代码后,将其粘贴到我们之前的demo源码中,并将其单独封装到一个方法里面,以便之后调用:
func queryBD(word string) {
client := &http.Client{}
var data = strings.NewReader("kw=" + word)
req, err := http.NewRequest("POST", "https://fanyi.baidu.com/sug", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
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("Connection", "keep-alive")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Cookie", `BIDUPSID=C800CE5CD446FC3EB5BF645BA351081E; PSTM=1629005484; BDUSS=d1ZnVqSGVmTH43LXh5UDRSRDR3WTNoQWdLajY0dlNQMW1ZRllSSEhiUVZOVUJoRVFBQUFBJCQAAAAAAAAAAAEAAAC029PNwvrL8Mer0uZ0cnoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWoGGEVqBhhTH; BDUSS_BFESS=d1ZnVqSGVmTH43LXh5UDRSRDR3WTNoQWdLajY0dlNQMW1ZRllSSEhiUVZOVUJoRVFBQUFBJCQAAAAAAAAAAAEAAAC029PNwvrL8Mer0uZ0cnoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABWoGGEVqBhhTH; __yjs_duid=1_2f34bb903ff54977c104c3c8f5039cb41629028188136; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; HISTORY_SWITCH=1; BAIDUID=3299D08E603EF5171F898A6296DB47C3:FG=1; BAIDU_WISE_UID=wapp_1631591012256_912; APPGUIDE_10_0_2=1; BAIDUID_BFESS=3299D08E603EF5171F898A6296DB47C3:FG=1; RT="z=1&dm=baidu.com&si=utj8eu5533d&ss=l2rdvgwu&sl=2&tt=2at&bcn=https%3A%2F%2Ffclog.baidu.com%2Flog%2Fweirwood%3Ftype%3Dperf&ld=34c&ul=bbh&hd=bcs"; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1649938460,1650448079,1650869079,1651919899; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1651920186; ab_sr=1.0.1_ZDI3OWNjNWQ0NmNlNzUxNzEzNTllMTYxYTc5MmU2MDg3ZWYyYjU2MTQzY2VmNDc5MjFlMzYzODdjYmFmMWVjYjNmODdkODM3MGViZjI2N2QyOTRkN2NkNjQ4NGE5MTY2OWRlODMzZTYxN2EyYmQzNTFlMTgxOGNmNzI3YTE2ZWMwMTcwMWI3YWM4MGI3NzQ4YWRmNjNjYzE4ZTFhMDFkMjFmNGIxNmRlYTQyNmFmYzdhZWM2NDQyMzhmYzdhMmRi`)
req.Header.Set("Origin", "https://fanyi.baidu.com")
req.Header.Set("Referer", "https://fanyi.baidu.com/?aldtype=16047")
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.41 Safari/537.36 Edg/101.0.1210.32")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
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"`)
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 DictResponseBD
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
fmt.Println(word," ",dictResponse.DictResDataBD[0].V)
}
定义响应结构
能够发送请求后,我们还需要将返回的数据(json数据)解析为go中的结构体类型,以便取得我们需要的信息。
然鹅要自己手动敲代码定义这个繁杂的返回数据结构实在太麻烦啦,还容易出错。这里我使用直播课中提到的工具:oktools.net来完成这个过程,最后得到以下类型定义:
type AutoGenerated struct {
Errno int `json:"errno"`
Data []struct {
K string `json:"k"`
V string `json:"v"`
} `json:"data"`
}
将其贴入源代码中,然后我们只要稍微调整一下上面的queryBD函数,最后也在main函数中调用queryBD,完成!
这样就完成了另一个翻译引擎的添加,效果如下:
针不戳!