这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
课程总结
- 学习了 Go 的基础语法,包括多种变量定义方式、流程控制、数组切片、Map、结构体、异常处理、字符串、Json、Time、命令行等等。
- 掌握 Go 语言中关于随机数生成、控制台输入输出流等技巧。
- 掌握 Go 中通过 Http 请求获取相应内容,并将其反序列化为 Go 结构体的方法。
- 掌握 Go 搭建简单代理服务器的方法。
作业
猜谜游戏
一些重点:
-
使用
math/rand包中的 rand 时,需要提前指定随机数种子,不然每次运行时产生的随机数固定。- 随机种子赋值可以用运行时的时间戳,详见代码
-
关于 bufio,它设置了一个输入输出缓冲区来加快速度,避免对底层存储系统的多次访问。更深层次的原理可以参考:juejin.cn/post/705826…
-
关于 fmt.Scanf 的使用可以参考:blog.csdn.net/putyourhear…
下面附上作业,使用 scanf 代替 bufio 后的代码:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
fmt.Println("Please input your guess")
for {
guess := 0
_, err := fmt.Scanf("%d", &guess)
if err != nil {
fmt.Println("An error occured while reading input. Please try again", err)
continue }
if guess > secretNumber {
fmt.Println("Your guess is bigger than the secret number. Please try again")
} else if guess < secretNumber {
fmt.Println("Your guess is smaller than the secret number. Please try again")
} else {
fmt.Println("Correct, you Legend!")
break
}
}
}
在线词典
作业一,添加了百度翻译作为第二翻译引擎支持。
作业二,使用 channel 来同步两个协程,只要其中有一个协程写入 channel,则另一个不再打印结果。这样就可以取最快的请求返回结果。
具体实现过程中,由于百度翻译 API 中的 sign 值是前端生成的,具体算法比较复杂,所以这里无法只根据查询单词内容返回结果,这里就没再深究了,如果使用 Python 爬取的话,有已经写好的库可以用:blog.csdn.net/qq_30162859…
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"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 {
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"`
}
type BaiduDictResponse struct {
DictResult struct {
SimpleMeans struct {
WordName string `json:"word_name"`
From string `json:"from"`
WordMeans []string `json:"word_means"`
Exchange struct {
WordPl []string `json:"word_pl"`
WordEst []string `json:"word_est"`
WordEr []string `json:"word_er"`
} `json:"exchange"`
Tags struct {
Core []string `json:"core"`
Other []string `json:"other"`
} `json:"tags"`
Symbols []struct {
PhEn string `json:"ph_en"`
PhAm string `json:"ph_am"`
Parts []struct {
Part string `json:"part"`
Means []string `json:"means"`
} `json:"parts"`
PhOther string `json:"ph_other"`
} `json:"symbols"`
} `json:"simple_means"`
Lang string `json:"lang"`
} `json:"dict_result"`
}
func query(word string, c chan int) {
client := &http.Client{}
// 构造请求 body 结构体,然后序列化为 Json 字符串
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 DictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
if len(c) == 1 {
close(c)
return
}
c <- 1
fmt.Println(word, "UK:", dictResponse.Dictionary.Prons.En, "US:", dictResponse.Dictionary.Prons.EnUs)
for _, item := range dictResponse.Dictionary.Explanations {
fmt.Println(item)
}
}
func query_by_baidu(word string, c chan int) {
client := &http.Client{}
var data = strings.NewReader(fmt.Sprintf("from=en&to=zh&query=%v&transtype=enter&simple_means_flag=3&sign=262931.57378&token=a96c5437b49673a096f48b66094903b7&domain=common", word))
req, err := http.NewRequest("POST", "https://fanyi.baidu.com/v2transapi?from=en&to=zh", data)
if err != nil {
log.Fatal(err)
}
req.Header.Set("Accept", "*/*")
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("Acs-Token", "1673769896714_1673781839135_/jNTmMdug05eaCQYNoVx1yA3nMqigRtFMSJAlz/zUNGC0gd2BpH8RupkqxzXZl7hL+rUhzPwH1PJLpRiww9t5nFbOZgfjWkurDnJrk3xr7FZOu0sT2mCiZqzpnxgRTscN50WTaELwA6ls5TBdq1ldPXAt1NyhicAatngXIBG2GnDew9M/Iql+bVI7Hdsumedin1lZeUaXz1CpzTQzqgan9WClE9E0bNWQZjCDEi5lnF3qkfD8XuwNOSNAGeiHcvIOqlGBvOjTZ9v1idYrahoQ3JDBvlZ/4gLOtuZ0xRx8XNEnSE9WEKqMkqbRajkEnsjmsu5z3MGQUkGQ2caJvYJsQ==")
req.Header.Set("Connection", "keep-alive")
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Cookie", "BAIDUID=8C8906FD9A2F5428E482BA2B3A171413:FG=1; BAIDUID_BFESS=8C8906FD9A2F5428E482BA2B3A171413:FG=1; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1673777565; APPGUIDE_10_0_2=1; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1673781835; ab_sr=1.0.1_Y2RmNDQxNjMzNTM2N2VhMzZiMjMwOTBkNjAxNTVmYzNmYzFmZDlhMGNmNDE0MjkxODY3MmZlYzMxZTM0ZTYzMTg5MGMzMDJkNGE3ZWQyNjgyZTIwZTg2NzdkZDZmZDQ0ZmFhZGY3OWJiOTdjZmY4YmJiY2U0OTYxMzA1Mzg4ZDk4YTEyMjdkZWViZjljMjBiNjczMzk0YjRhOTQ4MWFhMw==")
req.Header.Set("Origin", "https://fanyi.baidu.com")
req.Header.Set("Referer", "https://fanyi.baidu.com/")
req.Header.Set("Sec-Fetch-Dest", "empty")
req.Header.Set("Sec-Fetch-Mode", "cors")
req.Header.Set("Sec-Fetch-Site", "same-origin")
req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76")
req.Header.Set("X-Requested-With", "XMLHttpRequest")
req.Header.Set("sec-ch-ua", `"Not?A_Brand";v="8", "Chromium";v="108", "Microsoft Edge";v="108"`)
req.Header.Set("sec-ch-ua-mobile", "?0")
req.Header.Set("sec-ch-ua-platform", `"macOS"`)
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)
}
var dictResponse BaiduDictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
if len(c) == 1 {
close(c)
return
}
c <- 1
if len(dictResponse.DictResult.SimpleMeans.Symbols) == 0 {
fmt.Println("Sorry, the word was not found")
return
}
fmt.Println(word, "UK:", dictResponse.DictResult.SimpleMeans.Symbols[0].PhEn, "US:", dictResponse.DictResult.SimpleMeans.Symbols[0].PhAm)
for _, item := range dictResponse.DictResult.SimpleMeans.Symbols[0].Parts {
fmt.Println(item)
}
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, `usage: simpleDict WORD
example: simpleDict hello
`)
os.Exit(1)
}
word := os.Args[1]
c := make(chan int, 2)
go query(word, c)
go query_by_baidu(word, c)
<-c
}