Go语言通过API接口解析JSON并批量下载图片
本文介绍使用Go语言开发一个简单的图片下载工具,核心流程包括:调用API获取JSON数据、解析JSON提取图片标识、构建图片URL、以及并发或串行保存图片至本地文件夹。
实现目标与准备
本示例旨在通过Go脚本自动化下载指定主题的高清壁纸(如1920x1200分辨率)。主要技术点涉及HTTP客户端请求、JSON数据解析及文件系统操作。在开始之前,需要确保已安装Go环境,并使用go get github.com/bitly/go-simplejson安装第三方JSON解析库。
代码结构与核心逻辑
第1步:定义常量和数据结构
首先定义存储根目录、超时时间及API模板字符串。同时创建一个结构体Wallpaper用于映射JSON中的关键字段(PID、URL、宽高),便于后续处理。
package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"github.com/bitly/go-simplejson"
)
const (
DataRoot = "./tmp/" // 存放封面图的根目录
TimeoutLimit = 10 // 设置超时时间(秒)
// API URL模板,{pid}为占位符
PageUrl = "http://api.lovebizhi.com/macos_v4.php?a=category&spdy=1&tid=3&order=hot&color_id=3&device=105&uuid=436e4ddc389027ba3aef863a27f6e6f9&mode=0&retina=0&client_id=1008&device_id=31547324&model_id=105&size_id=0&channel_id=70001&screen_width=1920&screen_height=1200&bizhi_width=1920&bizhi_height=1200&version_code=19&language=zh-Hans&jailbreak=0&mac=&p={pid}"
)
type Wallpaper struct {
Pid int
Url string
Width int
Height int
}第2步:实现图片保存函数
编写SaveImage函数,接收Wallpaper指针。该函数负责根据分辨率创建子目录(若不存在),然后发起GET请求获取图片流,并写入本地文件。
注意:生产环境中建议增加错误处理和重试机制。
func SaveImage(paper *Wallpaper) {
res, err := http.Get(paper.Url)
defer res.Body.Close()
if err != nil {
fmt.Printf("%d HTTP ERROR:%s\n", paper.Pid, err)
return
}
// 按分辨率创建目录
Dirname := DataRoot + strconv.Itoa(paper.Width) + "x" + strconv.Itoa(paper.Height) + "/"
if !isDirExist(Dirname) {
os.MkdirAll(Dirname, 0755)
fmt.Printf("dir %s created\n", Dirname)
}
// 从URL中提取文件名
filename := filepath.Base(paper.Url)
dst, err := os.Create(Dirname + filename)
if err != nil {
fmt.Println("%d CREATE FILE ERROR:%s\n", paper.Pid, err)
return
}
// 复制数据流到文件
io.Copy(dst, res.Body)
}
func isDirExist(path string) bool {
p, err := os.Stat(path)
if err != nil {
return os.IsExist(err)
}
return p.IsDir()
}第3步:主程序逻辑与JSON解析
在main函数中,遍历分页参数(此处示例仅演示前几页)。替换URL中的{pid}占位符,发送请求获取JSON Body。使用simplejson库解析JSON,定位到data数组,遍历每一项提取file_id。由于API返回的file_id格式特殊,这里使用格式化转换后转为整数,进而构建最终的大图URL进行下载。
func main() {
// 检查并创建根目录
if !isDirExist(DataRoot) {
os.MkdirAll(DataRoot, 0755)
fmt.Println("dir %s created", DataRoot)
}
// 模拟分页循环 (示例仅处理页码1和2)
for pid := 1; pid <= 2; pid++ {
url := strings.Replace(PageUrl, "{pid}", strconv.Itoa(pid), -1)
fmt.Printf("Processing page: %d\n", pid)
response, err := http.Get(url)
if err != nil {
fmt.Println(err)
continue
}
body, _ := ioutil.ReadAll(response.Body)
response.Body.Close()
js, err := simplejson.NewJson(body)
if err != nil {
fmt.Println("JSON Parse Error")
continue
}
// 遍历 data 数组
data := js.Get("data").MustArray()
for _, v := range data {
if m, ok := v.(map[string]interface{}); ok {
if fileIDRaw, exists := m["file_id"]; exists {
// 处理特殊的 JSON Number 类型
vv := fmt.Sprintf("%s", fileIDRaw)
imgid, err := strconv.Atoi(vv)
if err != nil {
continue
}
// 构造高清大图链接 (假设 CDN 规则)
imgUrl := fmt.Sprintf("http://s.qdcdn.com/c/%d,1920,1200.jpg", imgid)
paper := &Wallpaper{
Pid: imgid,
Url: imgUrl,
Width: 1920,
Height: 1200,
}
SaveImage(paper)
}
}
}
}
fmt.Println("All jobs done.")
}注意事项与排错
- API变动风险:原文使用的API域名和参数结构可能随服务商更新而失效。如果运行后无法解析JSON或获取不到URL,请检查API响应体的实际结构。
- 依赖库版本:
go-simplejson是一个较早期的库,建议在现代Go项目中考虑使用标准库encoding/json结合Struct Tag进行更规范的解析。 - 资源合规:爬取和下载第三方平台内容时,请遵守网站的服务条款和版权规定,仅限个人学习研究使用。
总结
通过上述步骤,我们实现了一个基于Go语言的简单爬虫脚本,能够自动化地从API获取JSON数据并下载对应资源。掌握JSON解析和网络IO是Go语言开发实用工具的基础技能。
以上就是Go语言读取JSON并下载高清图片的详细内容,更多关于Go语言网络编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









