2 在线词典
调用第三方API查询单词翻译
使用go语言发送HTTP请求,解析json
2.1 抓包
彩云科技在线翻译:fanyi.caiyunapp.com
在网络——>dict——>右键——>复制——>复制为cURL(bash)
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
cURL(客户端URL)是一个开放源代码的命令行工具,也是一个跨平台的库(libcurl),用于在服务器之间传输数据,并分发给几乎所有新的操作系统。
cURL编程用于需要通过Internet协议发送或接收数据的几乎任何地方。
curl 'https://api.interpreter.caiyunai.com/v1/dict' \
-H 'authority: api.interpreter.caiyunai.com' \
-H 'accept: application/json, text/plain, */*' \
-H 'accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,ja;q=0.6,en-US;q=0.5' \
-H 'app-name: xy' \
-H 'content-type: application/json;charset=UTF-8' \
-H 'device-id: 2d1d90c19f0287edbd5a561fceaea093' \
-H 'origin: https://fanyi.caiyunapp.com' \
-H 'os-type: web' \
-H 'os-version;' \
-H 'referer: https://fanyi.caiyunapp.com/' \
-H 'sec-ch-ua: "Microsoft Edge";v="113", "Chromium";v="113", "Not-A.Brand";v="24"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
-H 'sec-fetch-dest: empty' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-site: cross-site' \
-H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.50' \
-H 'x-authorization: token:qgemv4jr1y38jyq6vhvi' \
--data-raw '{"trans_type":"en2zh","source":"good"}' \
--compressed
2.2 代码生成
代码生成网址:curlconverter.com/#go
package main
import (
"fmt"
"io"
"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("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,ja;q=0.6,en-US;q=0.5")
req.Header.Set("app-name", "xy")
req.Header.Set("content-type", "application/json;charset=UTF-8")
req.Header.Set("device-id", "2d1d90c19f0287edbd5a561fceaea093")
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", `"Microsoft Edge";v="113", "Chromium";v="113", "Not-A.Brand";v="24"`)
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/113.0.0.0 Safari/537.36 Edg/113.0.1774.50")
req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
bodyText, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", bodyText)
}
2.3 生成request body
将结构体初始化后,调用JSON.marshaler得到序列化后的字符串(字节数组)
使用bytes.NewReader()获得data
2.4 解析response body
将json字符串转为对应的结构体:oktools.net/json2go
type AutoGenerated 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"`
}
2.5 打印结果
fmt.Println(word,"UK:",dictResponse.Dictionary.Prons.En,"US:",dictResponse.Dictionary.Prons.EnUs)
for _,item := range dictResponse.Dictionary.Explanations{
fmt.Println(item)
}
2.6 运行
2.7 代码
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
//"os"
"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 {
} `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 []interface{} `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) // 创建请求,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,ja;q=0.6,en-US;q=0.5")
req.Header.Set("app-name", "xy")
req.Header.Set("content-type", "application/json;charset=UTF-8")
req.Header.Set("device-id", "1cd4889aebd2e8e18092825ec1af5743")
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", `"Microsoft Edge";v="113", "Chromium";v="113", "Not-A.Brand";v="24"`)
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/113.0.0.0 Safari/537.36 Edg/113.0.1774.42")
req.Header.Set("x-authorization", "token:qgemv4jr1y38jyq6vhvi")
resp, err := client.Do(req) // 发起请求
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close() // 避免资源泄露,defer手动关闭流,会在函数结束之后运行
bodyText, err := io.ReadAll(resp.Body) // 读取响应
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != 200{
log.Fatal("bad StatusCode:",resp.StatusCode,"body",string(bodyText)) // 错误的状态码,如404
}
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 main() {
// 在命令行go run后输入查询单词
/* if len(os.Args) != 2{
fmt.Fprintf(os.Stderr,`usage:simpleDict WORD example: simpleDict hello`)
os.Exit(1)
}
word := os.Args[1] */
var word string
for{
fmt.Print("\n请输入要查询的单词(输入0结束):")
_, err := fmt.Scanf("%v\n", &word)
if err != nil{
fmt.Println("读取输入出现错误,请重试!",err)
continue
}
word = strings.Trim(strings.TrimSuffix(word, "\n"), "\r")
if word=="0"{
break
}
query(word)
}
}