DOIFOR技术Golang实现获取Bing的每日一图
DOIFOR技术Golang实现获取Bing的每日一图

Golang实现获取Bing的每日一图

技术

实现方法来自:利用Api获取必应的每日一图

接口分析

主要api是:

https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1

响应体如下:

{
    "images": [
        {
            "startdate": "20240229",
            "fullstartdate": "202402291600",
            "enddate": "20240301",
            "url": "/th?id=OHR.Schmetterlingswiese_ZH-CN3740804088_1920x1080.jpg&rf=LaDigue_1920x1080.jpg&pid=hp",
            "urlbase": "/th?id=OHR.Schmetterlingswiese_ZH-CN3740804088",
            "copyright": "德国草地上的蝴蝶 (© Albert Fertl/Getty Images)",
            "copyrightlink": "https://www.bing.com/search?q=%E8%9D%B4%E8%9D%B6&form=hpcapt&mkt=zh-cn",
            "title": "蝶舞翩跹",
            "quiz": "/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20240229_Schmetterlingswiese%22&FORM=HPQUIZ",
            "wp": true,
            "hsh": "00894a0ae6a40ff698e21ce2afdd33eb",
            "drk": 1,
            "top": 1,
            "bot": 1,
            "hs": []
        }
    ],
    "tooltips": {
        "loading": "正在加载...",
        "previous": "上一个图像",
        "next": "下一个图像",
        "walle": "此图片不能下载用作壁纸。",
        "walls": "下载今日美图。仅限用作桌面壁纸。"
    }
}

主要业务逻辑实现

package service

import (
    "encoding/json"
    "io"
    "log"
    "net/http"
    "time"
)

// from page :https://cloud.tencent.com/developer/article/2086721
type BingImage struct {
    Bot           int    `json:"bot"`
    Copyright     string `json:"copyright"`
    CopyrightLink string `json:"copyrightlink"`
    Drk           int    `json:"drk"`
    EndDate       string `json:"enddate"`
    FullStartDate string `json:"fullstartdate"`
    Hs            []int  `json:"hs"`
    Hsh           string `json:"hsh"`
    Quiz          string `json:"quiz"`
    StartDate     string `json:"startdate"`
    Title         string `json:"title"`
    Top           int    `json:"top"`
    Url           string `json:"url"`
    UrlBase       string `json:"urlbase"`
    Wp            bool   `json:"wp"`
}

type BingToolTips struct {
    Loading  string `json:"loading"`
    Next     string `json:"next"`
    Previous string `json:"previous"`
    WallE    string `json:"walle"`
    WallS    string `json:"walls"`
}

type BingResponse struct {
    Images   []BingImage  `json:"images"`
    Tooltips BingToolTips `json:"tooltips"`
}

type Picture struct {
    Title     string `json:"title"`
    URL       string `json:"url"`
    Copyright string `json:"copyright"`
}

var picture *Picture
var lastTime time.Time

func GetPicture() *Picture {
    if picture != nil && isToday(lastTime) {
        return picture
    }
    lastTime = time.Now()
    picture = getNewPicture()
    return picture
}

func isToday(t time.Time) bool {
    now := time.Now() // 获取当前时间
    return t.Year() == now.Year() && t.Month() == now.Month() && t.Day() == now.Day()
}

func getNewPicture() *Picture {
    resp, err := http.Get("https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1")
    if err != nil {
        log.Fatal(err)
    }

    defer func(Body io.ReadCloser) {
        err := Body.Close()
        if err != nil {
            log.Fatal(err)
        }
    }(resp.Body)
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }

    response := BingResponse{}
    err = json.Unmarshal(body, &response)
    if err != nil {
        log.Fatal(err)
    }

    if len(response.Images) > 0 {
        image := response.Images[0]
        return &Picture{
            Title:     image.Title,
            Copyright: image.Copyright,
            URL:       "https://www.bing.com" + image.Url,
        }
    }

    return nil
}

说明:

  1. 结构体的属性名首字母均为大写,因为涉及到Json的序列化,首字母小写在Golang中意味着“私有”,私有的属性无法完成序列化。
  2. picture声明为指针类型,主要是保证全局只存在一份数据,也方便做缓存

对外暴露接口

r.GET("/image", func(context *gin.Context) {
        context.PureJSON(200, service.GetPicture())
    })

说明:

  1. 这个地方使用的是 context.PureJson() ,其主要原因是 context.Json()会对参数中的特殊字符进行转义,接口中的&字符转义后图片地址将无法正常访问。而PureJson()则可原封不动的将数据返回。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注