go语言实现命令行在线词典 | 青训营

41 阅读4分钟

本篇文章主要梳理总结了如何使用go语言,并且在一些代码生成工具的帮助下实现命令行在线词典的功能,以下是具体实践过程和走过的一些弯路(调错过程)

(一)抓包

(1)打开“彩云翻译网页”:[

fanyi.caiyunapp.com/

](fanyi.caiyunapp.com/)

(2)右键->检查

(3)在左边的英文区域输入英文->点击“翻译按钮”

(4)点击开发者工具中的“网络”->从下往上寻找请求方法为POST的dict文件

(5)点击“负载”进行查看(点击“翻译”时触发了POST请求,其参数是json,json里面包括2个字段source:要翻译的单词;trans_type:翻译方式如英译中)

(二)主体代码生成

(1)右键请求->复制->复制为cURL(bash)

(2)打开“主体代码生成网址”:[

curlconverter.com/#go

](curlconverter.com/#go)

(3)将复制的内容粘贴进去,选择go语言,自动生成代码

报错:.\main.go:49:19: undefined: io.ReadAll

原因:go的版本和io.ReadAll不匹配

修改:将导入的包"io"改为"io/ioutil" 将bodyText, err := io.ReadAll(resp.Body)改为bodyText,err := ioutil.ReadAll(resp.Body)

直到修改到可以打印出一大串返回的json请求如下即可:

(三)生成request body

(1)定义请求结构体

(2)new一个结构体变量,初始化字段

(3)序列化request变成一个数组

报错:undefined: json及undefined: bytes

修改:导入包"encoding/json"及"bytes"

(4)转化为data

报错:data redeclared in this block

原因:data已经定义过

修改:删除导入的包"strings"及var data =strings.NewReader(`{"trans_type":"en2zh","source":"network"}`)

直到终端可以输出如下信息:

(5)结构体代码生成

打开“结构体生成网址”:[

oktools.net/json2go

](oktools.net/json2go)

打开“彩云小译”界面,复制“响应”的内容到上述页面左边的JSON框中

点击“转换-嵌套”得到go语言结构体

将得到的结构体粘贴至代码中

(6)删除打印语句:fmt.Printf("%s\n", bodyText)

(7)增加报错检验:

(8)增加返回结构体变量:

(9)更改打印语句:

(10)修改函数主体:

(11)写一个新的main函数:

报错:cannot use os.Stderr (type *os.File) as type string in argument to fmt.Printf

原因:os.Stderr 是一个指向标准错误输出的文件对象的指针,无法直接转换为字符串类型

修改:将Printf改为Fprintf

(12)导入包查漏补缺

运行程序

命令1:go run .\main.go

报错1:usage:simpleDict WORD example:simpleDict helloexit status 1

原因:程序在没有提供命令行参数的情况下执行,或者提供的命令行参数不符合期望的格式

命令2:go run .\main.go hello

(13)可以正常运行,但是如果我们输入go run .\main.go 你好,可以发现程序并不报错,但是也无法正常给出翻译。因为我们选择的翻译类型为英译中,所以需要增加判断输入单词是否为英文单词的方法:

以上步骤都完成后,就可以实现【在线词典onlineDictionary】的功能啦!

下面是完整代码:

// 查询一个单词,输出其音标、注释package mainimport (    "fmt"    "io/ioutil"    "log"    "net/http"    "encoding/json"    "bytes"    "strings"    "os")//定义请求结构体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 {    } `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("authority", "api.interpreter.caiyunai.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("app-name", "xy")    req.Header.Set("content-type", "application/json;charset=UTF-8")    req.Header.Set("device-id", "43253aa06c2732303c265c61e036e33b")    req.Header.Set("origin", "https://fanyi.caiyunapp.com")    req.Header.Set("os-type", "web")    req.Header.Set("os-version", "")    req.Header.Set("referer", "https://fanyi.caiyunapp.com/")    req.Header.Set("sec-ch-ua", `"Chromium";v="112", "Microsoft Edge";v="112", "Not:A-Brand";v="99"`)    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", "cross-site")    req.Header.Set("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.46")    req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")    //发起请求    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 DictResponse    err = 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() {    if len(os.Args) != 2 {        fmt.Fprintf(os.Stderr,"usage:simpleDict WORD example:simpleDict hello")        os.Exit(1)    }    word := os.Args[1]    if ContainsEnglish(word) {        query(word)        return     }     fmt.Println("Please input an English word.")    return}