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中的区域。

原文链接:鱼塘主

相关推荐
deli00733 分钟前
32K 上下文塞满后,AI 最先忘掉什么?120 轮对话实测
前端
deli0072 小时前
手机拍灯为什么有一条条黑纹?PWM 240Hz 实测
前端
wangruofeng6 小时前
AI Models 1.1.0 发布,查大模型价格、对比模型和找 API 地址
前端·aigc·ai编程
脚本自动化开发6 小时前
玩影之刃零,两张四千元级显卡怎么挑
后端
wangruofeng6 小时前
给前端开发者的 100 个设计参考网站
前端·设计
M--Y9 小时前
LangGraph 工作流模式
开发语言·javascript·python·langchain·大模型·llm·langgraph
星栈9 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技10 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户479492835691510 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
努力的小雨11 小时前
别再复制日志给AI了!我让Codex自己去观测云查报错
后端