字节后端青训营 day01

  第一天,学了些Golang的基础语法,然后做了三个小项目。

1. 猜数字

  随机生成一个0~100的整数,然后猜数,程序很简单,就不贴了。

2. 英汉字典程序

目的:查询一个单词,输出音标和释义,如下所示:

$ go run dictionary.go hello
hello UK: [ˈheˈləu]  US: [həˈlo]
int.喂;哈罗
n.引人注意的呼声
v.向人呼()

2.1 用网页的F12功能抓包

打开一个翻译网页,比如 https://fanyi.caiyunapp.com/
按F12可进入开发者工具,里面可以查看network,然后可以看到好多网页请求。
找到请求方式为“POST”的dict请求,里面有Payload和Preview。
在这里插入图片描述

其中,Payload是请求的信息,包含trans_typesource两个字段
在这里插入图片描述

Preview则是响应信息,包含了查询单词的相关信息,是个非常复杂的结构体
在这里插入图片描述

2.2 代码生成

上面这个URL请求可以用Go来写,而且可以自动生成相应代码。步骤如下:

首先,复制cURL。
在这里插入图片描述

然后,在 https://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":"hello"}`)
	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", "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6")
	req.Header.Set("app-name", "xy")
	req.Header.Set("content-type", "application/json;charset=UTF-8")
	req.Header.Set("device-id", "e3da338b14045a9a8f59777769d1c977")
	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="111", "Not(A:Brand";v="8", "Chromium";v="111"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Linux"`)
	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 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54")
	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)
}

最后输出的是web响应结果的json字符串:

{"rc":0,"wiki":{},"dictionary":{"prons":{"en-us":"[h\u0259\u02c8lo]","en":"[\u02c8he\u02c8l\u0259u]"},"explanations":["int.\u5582;\u54c8\u7f57","n.\u5f15\u4eba\u6ce8\u610f\u7684\u547c\u58f0","v.\u5411\u4eba\u547c(\u5582)"],"synonym":["greetings","salutations"],"antonym":[],"wqx_example":[["say hello to","\u5411\u67d0\u4eba\u95ee\u5019,\u548c\u67d0\u4eba\u6253\u62db\u547c"],["Say hello to him for me . ","\u4ee3\u6211\u95ee\u5019\u4ed6\u3002"]],"entry":"hello","type":"word","related":[],"source":"wenquxing"}}

2.3 JSON转换

web请求和响应的数据采用JSON格式,可以将其转化为Go结构体。
请求的结构体比较简单,可以直接手写:

type DictRequest struct {
	TransType string `json:"trans_type"`  // 表示翻译方式,比如英译中
	Source    string `json:"source"`      // 表示要翻译的单词
}

而响应的结构体非常复杂,依旧可以用代码生成:
在F12工具中,找到Preview,然后复制
在这里插入图片描述
进入 https://oktools.net/json2go 把刚刚复制的粘贴进去,然后就能把JSON字符串转为Go结构体:

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"`
}

和JSON转换相关的函数:

// 结构体 -> JSON字符串
func json.Marshal(v any) ([]byte, error)
// JSON字符串 -> 结构体
func json.Unmarshal(data []byte, v any) error

用法如下:

import (
	"encoding/json"
	"log"
	// ...
)

func main() {
	// ...
	request := DictRequest{TransType: "en2zh", Source: word}
	buf, err := json.Marshal(request)
	if err != nil {
		log.Fatal(err)
	}
	// ...
	var response DictResponse
	err = json.Unmarshal(bodyText, &response)
	if err != nil {
		log.Fatal(err)
	}
}

2.4 os 包

用 os 包可以读取程序的输入参数(类似C/C++的main参数),也能使用os.Exit()提前退出程序,实例如下:

if len(os.Args) != 2 {
		fmt.Println("usage error: need a input word")
		os.Exit(-1)
	}

2.5 完整程序

package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
)

type DictRequest struct {
	TransType string `json:"trans_type"`
	Source    string `json:"source"`
}

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)
	}
	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("authority", "api.interpreter.caiyunai.com")
	req.Header.Set("accept", "application/json, text/plain, */*")
	req.Header.Set("accept-language", "en-US,en;q=0.9,zh-CN;q=0.8,zh-TW;q=0.7,zh;q=0.6")
	req.Header.Set("app-name", "xy")
	req.Header.Set("content-type", "application/json;charset=UTF-8")
	req.Header.Set("device-id", "e3da338b14045a9a8f59777769d1c977")
	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="111", "Not(A:Brand";v="8", "Chromium";v="111"`)
	req.Header.Set("sec-ch-ua-mobile", "?0")
	req.Header.Set("sec-ch-ua-platform", `"Linux"`)
	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 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.54")
	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)
	}

	var response DictResponse
	err = json.Unmarshal(bodyText, &response)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s UK: %s  US: %s\n", response.Dictionary.Entry, response.Dictionary.Prons.En, response.Dictionary.Prons.EnUs)
	for i := 0; i < len(response.Dictionary.Explanations); i++ {
		fmt.Printf("%s\n", response.Dictionary.Explanations[i])
	}
}

func main() {
	if len(os.Args) != 2 {
		fmt.Println("usage error: need a input word")
		os.Exit(-1)
	}
	query(os.Args[1])
}

结果如下:

$ go run dictionary.go hello
hello UK: [ˈheˈləu]  US: [həˈlo]
int.喂;哈罗
n.引人注意的呼声
v.向人呼()
$ go run dictionary.go beauty
beauty UK: [ˈbjuːti]  US: [ˈbjutɪ]
n.美人;美丽;美观;佳丽;美的事物;好处;优点

3. SOCKS5 代理

未完待续…

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值