背景
想获取bing历史壁纸。
目标
获取到bing历史壁纸。
步骤
访问 https://www.bing.com/HPImageArchive.aspx?format=js&n=1 可以获取当天的bing壁纸。
调整n的值可以获取更多,但最多只能有8个。
无意间看到必应每日图片、私有图床壁纸查询Api - 学习 - Timeless提供的接口,免费,可直接调用。就有了如下代码。
如下共4个文件,代码基于springboot-2.2.10。
value object对象
package cn.example.bingimg;
import lombok.Data;
import java.io.Serializable;
/**
* 必应图片接口外层响应类
*/
@Data
public class BingImageResponse implements Serializable {
/**
* 错误码(0表示成功)
*/
private Integer errno;
/**
* 错误信息(成功时为空)
*/
private String errmsg;
/**
* 分页数据(核心数据)
*/
private BingImagePageData data;
}
package cn.example.bingimg;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 必应图片分页数据类
*/
@Data
public class BingImagePageData implements Serializable {
/**
* 图片总条数
*/
private Integer count;
/**
* 总页数
*/
private Integer totalPages;
/**
* 每页条数
*/
private Integer pageSize;
/**
* 当前页码
*/
private Integer currentPage;
/**
* 图片列表(内层数据)
*/
private List<BingImageInfo> data;
}
package cn.example.bingimg;
import lombok.Data;
import java.io.Serializable;
/**
* 必应图片详情信息类
*/
@Data
public class BingImageInfo implements Serializable {
/**
* 图片唯一ID(MongoDB风格ID)
*/
private String _id;
/**
* 图片标题
*/
private String title;
/**
* 图片版权信息(含来源和作者)
*/
private String copyright;
/**
* 图片完整URL(可直接访问)
*/
private String url;
/**
* 图片基础URL(不含尺寸参数)
*/
private String urlbase;
/**
* 图片日期(格式:yyyy-MM-dd)
*/
private String time;
}
测试方法入口
package cn.example;
import cn.example.bingimg.BingImageInfo;
import cn.example.bingimg.BingImagePageData;
import cn.example.bingimg.BingImageResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.junit.Test;
import org.springframework.http.HttpMethod;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;
/**
* .
*
* @since 2025-10-28
*/
@Slf4j
public class BingImageGather {
final RestTemplate restTemplate = new RestTemplate();
@Test
public void doGather() throws IOException {
String url = "https://api.timelessq.com/bing/list?&pageSize=10&page=";
int page = 1;
for (; ; ) {
BingImageResponse response = restTemplate.getForObject(url + page, BingImageResponse.class);
if (Objects.isNull(response)) {
break;
}
Integer errno = response.getErrno();
if (!Integer.valueOf(0).equals(errno)) {
log.warn("errno:{}", response.getErrmsg());
break;
}
BingImagePageData data = response.getData();
List<BingImageInfo> imageList = data.getData();
if (CollectionUtils.isEmpty(imageList)) {
break;
}
downloadImages(imageList);
page++;
}
}
/**
* 使用RestTemplate下载图片,返回字节数组
*/
private static byte[] downloadImage(RestTemplate restTemplate, String imageUrl) {
// 自定义响应提取器,将响应流转换为字节数组
ResponseExtractor<byte[]> responseExtractor = new ResponseExtractor<byte[]>() {
@Override
public byte[] extractData(ClientHttpResponse response) throws IOException {
// 读取响应输入流到字节数组
try (InputStream in = response.getBody();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buffer = new byte[4096];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return out.toByteArray();
}
}
};
// 发送GET请求,提取响应体字节数组
return restTemplate.execute(imageUrl, HttpMethod.GET, null, responseExtractor);
}
private void downloadImages(List<BingImageInfo> imageList) throws IOException {
for (BingImageInfo bingImageInfo : imageList) {
String url = bingImageInfo.getUrl();
byte[] imageBytes = downloadImage(restTemplate, url);
UriComponents components = UriComponentsBuilder.fromUriString(url).build();
String filename = components.getQueryParams().getFirst("id");
FileUtils.writeByteArrayToFile(new File("x:/bing/" + filename), imageBytes);
}
}
}
收工。