这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
本篇笔记主要讲解一下课后作业的思路
Part 1
这个比较简单,其实没有什么特殊需要注意的。
func main() {
maxNum := 100
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
// fmt.Println("The secret number is ", secretNumber)
fmt.Println("Please input your guess")
//reader := bufio.NewReader(os.Stdin)
var str string // 存储输入值
for {
//input, err := reader.ReadString('\n')
_, err := fmt.Scan(&str)
if err != nil {
fmt.Println("An error occured while reading input. Please try again", err)
continue
}
str = strings.Trim(str, "\r\n") // 消去无用换行
guess, err := strconv.Atoi(str) // 转类型
if err != nil {
fmt.Println("Invalid input. Please enter an integer value")
continue
}
fmt.Println("You guess is", guess)
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
}
}
}
个人用的是string类型去读,可以尽可能的接近原来的版本,并且有进行非法输入的判断。
Part 2
这里主要要寻找方便的搜索引擎支持,找了好多种,也尝试了多种搜索引擎,有百度翻译、有道翻译、搜狗翻译、360翻译等等,但是现在目前基本上都有进行保护,不能像原来的代码一样直接进行API请求获取到数据。最后采用的是金山词霸的API,需要对特殊参数进行解析才能成功获取到请求返回。
func demoByKingSoftQuery(word string) {
client := &http.Client{}
// 为了成功获取信息,组装请求中的会变化的timestamp和signature
timestamp := strconv.FormatInt(time.Now().Unix(), 10)
signature := generatorMD5("/dictionary/word/query/web" + "61000006" + timestamp + word + "7ece94d9f9c202b0d2ec557dg4r9bc")
url := "http://dict.iciba.com/dictionary/word/query/web?client=6&key=1000006×tamp=" + timestamp + "&word=" + word + "&signature=" + signature
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Fatal(err)
}
/*
.....请求头.....
*/
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))
}
//fmt.Println(string(bodyText)) // 打印全文进行检验
var dictResponse KingSoftDictResponse
err = json.Unmarshal(bodyText, &dictResponse)
if err != nil {
log.Fatal(err)
}
// 音标输出
for _, item := range dictResponse.Message.BaesInfo.Symbols {
fmt.Printf(word + " UK:[" + item.PhEn + "] US:[" + item.PhAm + "]\n")
}
// 音译输出
for _, item := range dictResponse.Message.BaesInfo.Symbols {
for _, part := range item.Parts {
fmt.Printf("%s", part.Part)
for _, mean := range part.Means {
fmt.Printf("%s;", mean)
}
fmt.Println()
}
}
fmt.Println("****************************分割线****************************")
waitGroup.Done()
}
根据注解可以知道,时间戳和signature是特殊参数,需要对其进行解析,这就是不断去搜索里面的JavaScript文件,去打断点寻找到函数运行,然后去知道特殊参数的加密是如何加密的。
Part 3
因为Go语言的特性,感觉直接开协程就可以完成这个需求。直接使用Sync包下的waitgroup计数器进行控制,等到两个协程全部完成之后主线程才结束。
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, `usage: simpleDict WORD example: simpleDict hello`)
os.Exit(1)
}
word := os.Args[1]
waitGroup.Add(2)
go demoByKingSoftQuery(word)
go demoByLingoCloudQuery(word)
waitGroup.Wait()
}
其中waitGroup.Done()在各自函数结束的时候调用即可将计数器自减1。
PS:课程用的转化得到的结构体有时候需要进行修饰一下,可以更好用,如果还是不行的话可以去寻找其他类似的网站,比如(json2struct.mervine.net/)
人生苦短,不如go浪一下。