后端与go实战-在线词典| 青训营笔记

51 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第5天。

在线词典这个实战学到了很多工具的使用,简单记录和讲解一下这个例子,并完成课后任务

1.翻译网址

网址:彩云小译 - 在线翻译 (caiyunapp.com)

F12打开检查界面,网页里查询一下任意单词,进入网络(Network),点击查看请求头为post的dict

image.png 标头(head) :请求头

负载(payload):请求的参数

预览:网站返回的结果

响应:请求路由返回的response

2.生成请求代码

网址:Convert curl to Go (curlconverter.com)

右键点击dict复制为cURL(bash),在网站中粘贴并生成go代码

image-20230127164025486.png

3.生成返回结构体

网址:oktools.net/

将响应结果复制到该网站,并生成go代码

image-20230127165702827.png 点击嵌套,使代码更紧凑,完成response的结构体

当然,只取部分属性用于结构体也是可以滴,但是golang是强类型语言,这样不佳

4. 代码解释

func query(word string) {
    client := &http.Client{}
    request := DictRequest{TransType: "en2zh", Source: word}    //请求参数的结构体
    buf, err := json.Marshal(request)   //将结构体编码为json格式
    if err != nil {
        log.Fatal(err)
    }
    //Reader实现了io.Reader接口,data可作为NewReaqest参数
    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)
    }
    //Body是个io流,需要关闭
    defer resp.Body.Close()
    //从Body中读出返回的json数据
    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
    //将json数据解码为结构体,可部分解码
    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 main() {
    var word string
    _, err := fmt.Scan(&word)
    if err!=nil{
        log.Fatal(err)
        return
    }
    query(word)
}
​

5.添加作业代码(新增引擎,并行两个请求)

type bingResponse []struct {
   DetectedLanguage struct {
      Language string `json:"language"`
      Score float64 `json:"score"`
   } `json:"detectedLanguage"`
   Translations []struct {
      Text string `json:"text"`
      Transliteration struct {
         Text string `json:"text"`
         Script string `json:"script"`
      } `json:"transliteration"`
      To string `json:"to"`
      SentLen struct {
         SrcSentLen []int `json:"srcSentLen"`
         TransSentLen []int `json:"transSentLen"`
      } `json:"sentLen"`
   } `json:"translations"`
}
​
func queryByBing(word string,ch chan string) {
   client := &http.Client{}
   //reqest&连接的信息
   request:="..."+word+"..."
   var data = strings.NewReader(request)
  //请求头为自动生成的代码
   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 bingRes bingResponse
   err=json.Unmarshal(bodyText,&bingRes)
   if err!=nil{
      log.Fatal(err)
   }
   for _, re := range bingRes {
      for _, item := range re.Translations {
         ch<-item.Text
      }
   }
​
}
​
func main() {
   var word string
   for{
      _, err := fmt.Scan(&word)
      if err!=nil{
         log.Fatal(err)
         return
      }
      ch1:=make(chan string)
      ch2:=make(chan string)
      //并发执行
      go queryByBing(word,ch1)
      go queryByCaiYun(word,ch2)
      //输出先返回的结果
      select {
      case caiyun:=<-ch2:
         fmt.Println(caiyun)
      case bing:=<-ch1:
         fmt.Println(bing)
      }
   }
}

参考

Go 语言的实战案例 - 掘金 (juejin.cn)