通过字节跳动后端青训营的第一节课后,学习到了如何实现一个命令行词典,也懂得了抓包相关知识,掌握了一些转换工具,在此进行记录并巩固。

思考

如果我们想实现一个命令行词典,自己手写接口肯定非常困难,于是我们想到使用浏览器中的开发者工具进行抓包。拿到接口后再在IDE中进行实现。

第一步:抓包

我们以彩云小译为例

我们首先在输入框中输入一个简单的单词实现一次翻译,例如这样

想用啥单词都行,都是一样的

之后我们F12或者右键检查打开浏览器开发者工具,并在其中选择网络项

在下面的请求中我们找到叫做dict的请求,并在标头中检查请求方法是否为POST

检查完毕之后就可以把将接口拿走,我们可以可以先选择将它复制为cURL(bash)

然后我们转到一个转译网站,它可以将cURL转换成Go语言的写法(并适用于其他多种语言)

我们先选择Go语言,再将我们刚才复制好的cURL粘贴进去

然后我们就可以在下面将Go语言复制进我们的IDE了

package mainimport ("fmt""io/ioutil""log""net/http""strings"
)func main() {client := &http.Client{}var data = strings.NewReader(`{"trans_type":"en2zh","source":"good"}`)req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)if err != nil {log.Fatal(err)}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("Connection", "keep-alive")req.Header.Set("Content-Type", "application/json;charset=UTF-8")req.Header.Set("Origin", "https://fanyi.caiyunapp.com")req.Header.Set("Referer", "https://fanyi.caiyunapp.com/")req.Header.Set("Sec-Fetch-Dest", "empty")req.Header.Set("Sec-Fetch-Mode", "cors")req.Header.Set("Sec-Fetch-Site", "cross-site")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")req.Header.Set("X-Authorization", "token:qgemv4jr1y38jyq6vhvi")req.Header.Set("app-name", "xy")req.Header.Set("os-type", "web")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)}fmt.Printf("%s\n", bodyText)
}

至此我们以及将命令行词典的第一步完成

第二步:自定义查询

我们可以看到因为我们在彩云小译中翻译的是单词go,所以后续的cURL以及拿到的Go语言代码中的"sourse"键值依旧是go,为了我们能自定义输入的单词,可以定义一个结构体

type DictRequest struct {TransType string `json:"trans_type"`Source    string `json:"source"`
}

这样之后就可以在主函数中自定义翻译请求,通过一个字节的方式传进去

request := DictRequest{TransType: "en2zh", Source: "good"}
buf, err := json.Marshal(request)
if err != nil {log.Fatal(err)
}
var data = bytes.NewReader(buf)

我们可以运行一下,会发现如果"source"中的值不变运行结果也不会改变

第三步:自定义返回值

在上两步的运行结果中我们可以发现传出来的值非常多,有许多值并不是我们需要的内容,所以我们可以将传回来的JSON转换成Go中的结构体,这样就可以自己选择需要的值

我们先回到刚才的彩云小译界面,选择标头旁边的预览,将里面的值复制下来

复制完之后我们可以使用一个在线转换工具进行转换,并在其中选择嵌套转换

然后将右边的结构体复制到Go中即可

我们可以在Go中将其打印出来

var dictResponse DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {log.Fatal(err)
}
fmt.Printf("%#v\n", dictResponse)

到这里我们的命令行词典马上就要完成了

第四步:命令行输入单词并查询所需的值

在第二步中实现了自定义查询,但是事实上并不是在命令行中输入,我们可以将词典搜索封装成一个函数在主函数中调用

fmt.Printf("请输入您想翻译的单词:")
var word string
_, err := fmt.Scanf("%v", &word)
if err != nil {fmt.Println(err)return
}query(word)

在query函数中打印我们需要的值

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

很多同学可能觉得这样我们的程序就完成了,可是我们并没有判断输入是否为英文,当在命令行输入中文时程序并不会报错,所以我们需要再编写一个判断输入是否为英文的函数

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

最终我们的程序大功告成,以下为完整代码

完整代码

package mainimport ("bytes""encoding/json""fmt""io/ioutil""log""net/http""strings"
)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)if err != nil {log.Fatal(err)}var data = bytes.NewReader(buf)req, err := http.NewRequest("POST", "https://api.interpreter.caiyunai.com/v1/dict", data)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)if err != nil {log.Fatal(err)}if resp.StatusCode != 200 {log.Fatal("bad StatusCode:", resp.StatusCode, "body", string(bodyText))}var dictResponse DictResponseerr = json.Unmarshal(bodyText, &dictResponse)if err != nil {log.Fatal(err)}fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)for _, item := range dictResponse.Dictionary.Explanations {fmt.Println(item)}
}func ContainsEnglish(str string) bool {dictionary := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"for _, v := range str {if strings.Contains(dictionary, string(v)) {return true}}return false
}func main() {fmt.Printf("请输入您想翻译的单词:")var word string_, err := fmt.Scanf("%v", &word)if err != nil {fmt.Println(err)return}if ContainsEnglish(word) {query(word)return}fmt.Println("翻译错误,请输入英文")return
}

测试

请输入您想翻译的单词:gold
gold UK: [gəuld] US: [gold]
n.黄金;金色;金币;财富
a.金的;金子做的;黄金色的进程 已完成,退出代码为 0
请输入您想翻译的单词:金子
翻译错误,请输入英文进程 已完成,退出代码为 0

使用Go语言实现单词翻译功能/simpledict 命令行词典相关推荐

  1. Python 打造基于有道翻译的命令行翻译工具(命令行爱好者必备)

    Python 打造基于有道翻译的命令行翻译工具(命令行爱好者必备) 之前基于百度写了一篇博文 Python 打造基于百度翻译的命令行翻译工具,本来这工具用得挺好的.但是没想到,近期处于不知道啥原因,不 ...

  2. c语言输入字符串以井号结束,想学好C语言必须得先学会自救(命令行必须以井号“#”开头 最后不能加分号“;”结尾)...

    想学好C语言必须得先学会自救(命令行必须以井号"#"开头 最后不能加分号";"结尾) 2018-11-24 [[编程学习]想学好C语言,必须得先学会自救]htt ...

  3. Go语言实践[回顾]教程03--Go语言的编译与运行的命令行

    Go语言实践[回顾]教程03--Go语言的编译与运行的命令行 Go语言是编译型静态语言 如何编译Go语言的源文件 如何执行(运行)编译后的文件 开发中如何编译后立即执行 总结 Go语言是编译型静态语言 ...

  4. c语言中的单词的意思及作用,C语言实现单词助手功能

    本文实例为大家分享了C语言实现单词小助手的具体代码,供大家参考,具体内容如下 单词小助手 (声明:此程序非原创,是在已有程序上进行一些修改和添加) 一.题目分析 题目要求: 1.改写程序为良好程序风格 ...

  5. mysql go命令行_Go语言调用mysql.exe和mysqldump命令行导入导出数据库

    最近准备将我平时写的ruby和python小工具推广到整个小组,以提高小组工作效率.但是效果不太理想,主要是脚本语言依赖环境,安装配置比较繁琐,组员们虽然很羡慕我的工具,但是愿意尝试很少. Go语言最 ...

  6. Windows中使用C语言实现打印彩色文字到命令行窗口

    本文记录的是在Windows中使用C语言自定义一个可以打印彩色文字的printf函数,函数原型如下: int colorful_printf(WORD color, const char* forma ...

  7. 【C 语言】文件操作 ( 学生管理系统 | 命令行接收数据填充结构体 | 结构体写出到文件中 | 查询文件中的结构体数据 )

    文章目录 一.学生管理系统 二.代码示例 一.学生管理系统 前两篇博客 [C 语言]文件操作 ( 将结构体写出到文件中并读取结构体数据 | 将结构体数组写出到文件中并读取结构体数组数据 ) [C 语言 ...

  8. linux的命令窗口,(翻译)Linux命令行(二)

    文件和目录操作 cd /home              进入'/home'目录 cd ..                     返回上一层目录 cd ../..             返回上 ...

  9. linux命令 翻译,(翻译)Linux命令行(一)

    这里的Linux命令行系列是翻译自http://www.linuxguide.it/的,如果你英语够好,推荐你去看原版的.这是第一篇,主要介绍关机重启等操作和查看系统信息等操作的命令. 关机重启等操作 ...

  10. AfterEffect插件--常规功能开发--命令行渲染--js脚本开发--AE插件

      AfterEffect(AE)插件是Adobe公司开发的特效制作软件,稳定快速的功能和特效,在视频制作领域使用非常广泛,本文向大家介绍如何在项目里进行命令行渲染功能.源代码如下所示: // Com ...

最新文章

  1. 项目前端页面框架介绍
  2. Linux命令 — 设置或查看网络配置命令ifconfig
  3. 对CORS OPTIONS预检请求的一些思考
  4. C语言 semaphore
  5. Objective-C中小怪兽的逻辑
  6. PHP中cURL的curl_getinfo函数返回的CURLINFO_HTTP_CODE是0
  7. Android中继承的Dialog导致程序崩溃
  8. ELMo ,LM:一串词序列的概率分布probability distribution over sequences of words
  9. 斐讯K2刷华硕固件教程
  10. $.ajax.submit,jQuery中的AjaxSubmit使用讲解
  11. robot framework 添加selenium2library显示红色
  12. 三极管开关电路_简析三极管开关电路设计
  13. 多维数据模型中维度、度量、层级理解
  14. 一个简洁的layui主题,可以用于旅游网页的制作
  15. bw项目抱佛脚入门资料-2.按照指标创建BW数据存储对象
  16. XMLHttpRequest cannot load 的解决方法
  17. 老毛桃怎样查看计算机桌面文件,桌面上的文件在PE里怎么找-win7在pe下的桌面文件,win7在pe下的桌面文件不见了...
  18. 谷歌Chrome超越苹果Safari 市场份额升至第三(每日关注2009.12.16)
  19. c语言一对多,NRF905一对多的有关问题
  20. 如何学习深度学习——我的高质量学习资源列表

热门文章

  1. 分类数据之列联表分析案例with sas
  2. 自媒体平台数据统计分析爬虫之【一点号】模拟登陆分析详解及数据统计接口详解
  3. Redis使用pipeline批量查询所有键值对以及multiGet用法
  4. vnc 键盘慢_在基于Web的VNC应用程序中支持多种键盘布局
  5. Cygwin安装教程【超详细】
  6. 数据新闻大趋势 释放可视化报道的力量------读后随笔
  7. android手机双开微信方法,微信双开太简单了!学会这几种方法,就能同时登录2个微信...
  8. 航拍南山区六个文化相关全景VR解读
  9. 达梦(DM)数据库常见问题详解
  10. python读写excel的图片_Python读取excel中的图片完美解决方法