分析过程
1.网页抓包
- 需要发出http请求,调用第三方API进行辅助翻译,本项目借助了彩云小译 - 在线翻译 (caiyunapp.com)
- 抓包 : 首先随便输入一个单词(如good),点击翻译,随后右键检查(或F12),在网络(network)中找到名称为dict的值(确认图示处为POST)
2.请求进行GO代码转换
打开代码生成网址,将复制的cURL粘贴进去就能得到请求对应的GO代码。
生成的代码如下:
&http.Client{}为创建一个httpclient,创建的时候可以指定一些参数,比如超时时间等,不指定就是不限制时间。
http.NewRequest创建一个http请求,参数为请求方式(GET/POST)、请求URL以及请求参数。
req.Header.Set设置请求头参数,有些参数不是必须的话可以删掉。
client.Do发起请求并返回内容以及错误信息。
resp为请求响应流,为了避免资源泄露,需要对流进行关闭。
defer一般用于资源的释放和异常的捕捉, defer语句会将其后面跟随的语句进行延迟处理,将会在程序进行最后的return之后再执行。如果一个函数中有多个defer的话,会从下往上执行,也就是最后被defer的语句,最先被执行.
3.JSON转化
- 因为请求得到的内容是个字符串,而且有很多不需要的信息,接下来就是要把得到的字符串转为
JSON。
需要定义一个结构体与请求后的response来对应起来用来接收数据,通过JSON反序列化到结构体里即可。
清除掉无用的字段消息,构建需要信息的结构体,而后对请求响应体进行JSON反序列化,代码如下:构造一个DictRequest结构体,用于接收Json,通过请求Json序列化爬取数据,注意结构体的变量要与Json一一对应,不然会报错
type request struct {
query string
from string
to string
appid string
salt string
sign string
}
type response struct {
From string `json:"from"`
To string `json:"to"`
TranslateResult []struct {
Src string `json:"src"`
Dst string `json:"dst"`
} `json:"trans_result"`
- 解析response body,进行Json的反序列化,还是要借助网站JSON转Golang Struct - 在线工具 - OKTools,找到抓包时的dict,把响应(response)那些Json字符串粘贴进去,点击转换-嵌套,效果如图(AutoGenerated后期将修改为DictResponse)
4代码封装
- .进行小小的修改,并将代码封装成一个函数
func query(word string),再在main函数里调用这个函数即可。
func query(query string) (response, error) {
request := request{
query: query,
from: "auto",
to: "zh",
appid: appid,
salt: salt,
sign: getSign(query),
}
data := url.Values{}
data.Set("q", request.query)
data.Set("from", request.from)
data.Set("to", request.to)
data.Set("appid", request.appid)
data.Set("salt", request.salt)
data.Set("sign", request.sign)
u, err := url.ParseRequestURI(host)
if err != nil {
log.Fatal(err)
return DictResponse{}, errors.New("bad response")
}
u.RawQuery = data.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
log.Fatal(err)
return DictResponse{}, errors.New("bad response")
}
client := &http.Client{}
req.Header.Add("Accept", "*/*")
req.Header.Add("Host", "fanyi-api.baidu.com")
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, err := client.Do(req)
if resp.StatusCode != 200 {
log.Fatal("bad StatusCode", resp.StatusCode)
return DictResponse{}, errors.New("bad response")
}
if err != nil {
log.Fatal(err)
return DictResponse{}, errors.New("bad response")
}
defer resp.Body.Close()
bodytext, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
return DictResponse{}, errors.New("bad response")
}
var response DictResponse
err = json.Unmarshal(bodytext, &response)
if err != nil {
log.Fatal(err)
return DictResponse{}, errors.New("bad response")
}
return response, nil
}
总结: 至此,便可以基本实现在GO编译器平台进行命令行操作了,这里就不进行展示了.此两次作业,从简到难,对于随机数小程序,可以较好地练习相应的GO语法知识,有一个很简单基本的运用.特别是此次在线词典的小项目,学会了很多网络请求方面的知识,HTTP协议,TCP握手,包与响应等等,同时也对于利用网络API进行二次创造利用,有了比较好的想法注意,虽然中间过程需要借助他人文档的支持,学习,但整体下来对于知识体系有了一个新的认识与了解