Nodejs获取bing每日图片

Nodejs保存每日bing图片

偶然看到github上的一个开源项目。用java写的,我来抄个作业。用nodejs实现~

我准备做成一个接口的形式,访问就直接返回当日的bing图片。当然这个图片得适应于更多场景~

所以,我对他做了一下设计:

  1. 可以自定义宽高
  2. 也可以传入size,这个size可以理解为等比例缩放。
  3. 会影响图片大小

由此得到了一个注释

js 复制代码
/** 
 * @description 获取必应图片
 * @param {Number} req.body.w 宽度
 * @param {Number} req.body.h 高度
 * @param {Number} req.body.size 图片大小
 * @returns {BinaryData} 图片二进制
 */

开始撸代码

这里我选择了比较方便的express

bash 复制代码
mkdir bing && cd bing && pnpm init
pnpm add express

# 安装node-fetch为我们做请求
pnpm add node-fetch

# 还需要安装一下sharp对我们的图片进行处理
pnpm add sharp

启动express

做了一下简单的router分离

js 复制代码
// app.js

import 'dotenv/config';
import express from "express"
import cors from "cors"
import imagesRouter from './src/router/images.js'

const app = express();
app.use(cors());

app.use("/images", imagesRouter);

app.get("/", (req, res) => { 
  res.send("Hello World");
})

app.listen(process.env.RUN_TIME_PORT, () => { 
  console.log(`Server running on port ${process.env.RUN_TIME_PORT}`);
})

到这里 我们的express服务器已经启动成功了~

useBing

其实bing的每日图片,bing提供了API,也就是

https://global.bing.com/HPImageArchive.aspx?format=js&idx=0&n=9&pid=hp&FORM=BEHPTB&uhd=1&uhdwidth=3840&uhdheight=2160&setmkt=%25s&setlang=en

访问他,获取数组中的第一个,就是今天的图片哦~

js 复制代码
// 请求
    const base = "https://www.bing.com";
    const reqUrl = base + '/HPImageArchive.aspx?format=js&idx=0&n=9&pid=hp&FORM=BEHPTB&uhd=1&uhdwidth=3840&uhdheight=2160&setmkt=%s&setlang=en';
    const data = await fetch(reqUrl)
    const json = await data.json()

分析一下返回的json

json 复制代码
{
  images:[
    {
      "startdate": "20231225",
      "fullstartdate": "202312251600",
      "enddate": "20231226",
      "url": "/th?id=OHR.BoxingDaySunrise_ZH-CN7431512686_UHD.jpg&rf=LaDigue_UHD.jpg&pid=hp&w=3840&h=2160&rs=1&c=4",
    },
    ....
  ]
}

需要的其实就url这个链接~。

这个链接会直接返回一个图片。

所以处理一下这个地方的BASE_URL='https://www.bing.com'+url

我们就得倒了图片的资源路径~

下载

当我们已经得倒了资源路径,就继续下载

js 复制代码
export async function downloadImage(src = '',name='bing.jpg') {
  const response = await fetch(src);
  const buffer = await response.buffer();
  fs.writeFileSync(BING_PATH(name), buffer)
}
  • src就是图片的资源路径
  • name图片存储路径

但是这个地方有个问题,我们总不能每次都去下载吧?

所以,就需要做一下判断。如果这个图片已经下载好了,那么就直接返回我们下载好的图片~

判断文件是否已经存在

我这里是直接用当前日期做的文件名,比较方便。 我们只需要遍历一下,存储bing文件夹下的文件,是否有以当前日期开头的文件就可以啦。

js 复制代码
export function bingIsExist() { 
  const today = dayjs().format("YYYY-MM-DD");
  const data = fs.readdirSync(BASE_PUBLIC_DIR + '/bing')
  const isExist = some(data, v => v.startsWith(`${today}`))
  return isExist
}

完整的useBing

js 复制代码
/**
 * 下载bing图片
 * 1. 判断今天的图片是否已经下载过了
 * 2. 如果没有下载过,那么就下载
 * 3. 如果下载过了,就直接返回本地文件
 * @returns {BinaryData} 图片二进制
 */
export async function useBing() {
  const canFind = bingIsExist()
  const toDay = dayjs().format("YYYY-MM-DD");
  if (!canFind) {
    const base = "https://www.bing.com";
    const reqUrl = base + '/HPImageArchive.aspx?format=js&idx=0&n=9&pid=hp&FORM=BEHPTB&uhd=1&uhdwidth=3840&uhdheight=2160&setmkt=%s&setlang=en';
    const data = await fetch(reqUrl)
    const json = await data.json()
    const url = json.images[0].url
    const realURL = base + url
    await downloadImage(realURL, toDay + ".jpg")
  }
  const data = fs.readFileSync(BING_PATH(toDay + ".jpg"))
  return data
}

接口返回

当我们工具函数都写完了,那么就需要在接口中开始调用,完成这个接口。

js 复制代码
router.get("/bing", async (req, res) => {
  const { w, h, size } = req.query // 需要使用body-paser哦
  const blob = await useBing()
  res.setHeader("Content-Type", "image/jpeg")
  // 中间使用sharp处理图片。就不多赘述,自行编写~很简单
  ...
  res.send(blob)
})

测试一下

还需注意一点,不同区域获取到的图片会有所不同。需要自己去处理,根据访问ip去定位,最后修改api中的区域。

原文链接:鱼塘主

相关推荐
想用offer打牌2 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX4 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法4 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端