练习 4.12: 流行的web漫画服务xkcd也提供了JSON接口。例如,一个 https://xkcd.com/571/info.0.json 请求将返回一个很多人喜爱的571编号的详细描述。
下载每个链接(只下载一次)然后创建一个离线索引。
编写一个xkcd工具,使用这些离线索引,打印和命令行输入的检索词相匹配的漫画的URL。
“https://xkcd.com/%d/info.0.json”.i请求链接,下载所有img链接
用一个map存储内容便于索引
type Xkcd struct {
Title string // 漫画标题
Img string // 图片链接
// Transcript string // 漫画的描述 : 用于搜索
}
var results = make(map[string]string)
func main() {
// 请求下载url
for i := 1; i < 150; i++ {
fmt.Printf("正在请求 %d \n", i)
url := fmt.Sprintf("https://xkcd.com/%d/info.0.json", i)
if result, err := Download(url); err != nil { // 下载链接
fmt.Println("[-]请求失败 :", err)
} else {
fmt.Printf("下载链接 : %v \t %v\n", result.Title, result.Img)
}
}
// 处理输入实现检索
if os.Args[1:] != nil {
for _, arg := range os.Args[1:] {
if val, ok := results[arg]; ok {
fmt.Printf("恭喜你查询成功!\n Title: %s\t Url:%s \n", arg, val)
} else {
fmt.Println("查无此title!")
}
}
}
}
func Download(url string) (*Xkcd, error) {
// 请求
// fmt.Println("正在请求")
resp, err := http.Get(url)
if err != nil {
return nil, err
}
// 错误代码处理
if resp.StatusCode != http.StatusOK {
resp.Body.Close() //关闭连接
return nil, fmt.Errorf(" query failed : %s", err) // 错误重写
}
// 正确内容解析
var result Xkcd // z准备接收json内容
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
resp.Body.Close()
return nil, err
}
// 解析完毕,返回
resp.Body.Close()
results[result.Title] = result.Img
return &result, err
}