1.数据来源于百度搜索置顶日历:
2.代码:
http调用及数据处理均采用了hutool, 也可以用别的工具。
hutool 依赖如下:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.2</version>
</dependency>
package com.visy.utils;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* @author visy.wang
* @description: 日历数据查询工具
* @date 2023/1/29 15:55
*/
@Slf4j
public class CalendarUtils {
public static void main(String[] args) {
JSONArray list = queryCalendarList(2023, 2);
//打印
if(list != null){
//只打印一行看看
System.out.println(JSONUtil.formatJsonStr(list.get(0).toString()));
}
}
/**
* 查询日历列表,注意:返回结果的oDate采用的时区是0时区
* @param year 年,如:2023
* @param month 月,如:2
* @return 返回当前月,上一个月以及下一个月的日历数据
*/
public static JSONArray queryCalendarList(int year, int month){
String url = "https://opendata.baidu.com/api.php";
//拼接参数
url = url + "?" + getQueryStr(year, month);
log.info("完整请求地址: {}", url);
//发起调用
String response = HttpUtil.get(url);
//可以看到返回的是JSONP
log.info("原始响应结果: {}", response);
//去除多余字符,提取JSON部分(返回结果为JSONP时)
String jsonStr = response.substring(response.indexOf("{"), response.lastIndexOf("}")+1);
log.info("JSON响应体: {}", jsonStr);
//解析返回结果
JSONObject json = JSONUtil.parseObj(jsonStr);
//仅当状态=0时调用成功
if(!"0".equals(json.getStr("status"))){
log.info("接口调用失败");
return null;
}
//提取data数组
JSONArray data = json.getJSONArray("data");
if(data.isEmpty()){
return null;
}
//取第一个元素
JSONObject data_0 = data.getJSONObject(0);
//提取almanac数组并返回
return data_0.getJSONArray("almanac");
}
private static String getQueryStr(int year, int month){
Map<String,Object> params = new HashMap<>();
params.put("tn", "wisetpl");
params.put("format", "json");
params.put("resource_id", "39043");
params.put("t", System.currentTimeMillis());
params.put("cb", "callback"); //不加这个参数返回结果为JSON,加了返回的是JSONP
params.put("query", year+"年"+month+"月");
StringBuffer qs = new StringBuffer();
params.forEach((k, v) -> {
qs.append(k).append("=").append(v).append("&");
});
return URLUtil.encode(qs.deleteCharAt(qs.length()-1).toString(), StandardCharsets.UTF_8);
}
}
3.输出
完整请求地址: https://opendata.baidu.com/api.php?t=1674981971139&query=2023%E5%B9%B42%E6%9C%88&format=json&resource_id=39043&tn=wisetpl&cb=callback
原始响应结果: /**/callback({"status":"0","t":"1674981971139","set_cache_time":"","data":[...]});
{
"oDate":"2022-12-31T16:00:00.000Z",
"year":"2023",
"lunarDate":"10",
"yj_from":"51wnl",
"isBigMonth":"1",
"lDate":"初十",
"lMonth":"腊",
"type":"h",
"gzMonth":"壬子",
"lunarMonth":"12",
"gzYear":"壬寅",
"month":"1",
"cnDay":"日",
"animal":"虎",
"term":"元旦",
"avoid":"栽种.安门.治病.作灶",
"gzDate":"己未",
"suit":"动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子",
"day":"1",
"lunarYear":"2022",
"status":"1"
}
4.字段说明:
字段名 | 描述 | 例子 |
---|---|---|
oDate | 时间(0时区) | 2022-12-31T16:00:00.000Z |
year | 年(阳历) | 2023 |
month | 月(阳历) | 1 |
day | 日(阳历) | 1 |
lunarYear | 年(农历) | 2022 |
lunarMonth | 月(农历) | 12 |
lunarDate | 日(农历) | 10 |
lMonth | 月(农历描述) | 腊 |
lDate | 日(农历描述) | 初十 |
gzYear | 年-干支 | 壬寅 |
gzMonth | 月-干支 | 壬子 |
gzDate | 日-干支 | 己未 |
animal | 生肖年 | 虎 |
cnDay | 星期描述(一二三四五六日) | 日 |
isBigMonth | 是否是农历大月(1-是) | 1 |
term | 节假日描述(含节气) | 元旦 |
status | 节假日状态(1-休假,2-补班) | 1 |
type | 节假日类型 | h |
yj_from | 数据来源 | 51wnl |
suit | 宜 | 动土.祈福.安床.架马.开厕.祭祀.入殓.成人礼.成服.除服.伐木.结网.开池.求子 |
avoid | 忌 | 栽种.安门.治病.作灶 |
5.附新地址
https://opendata.baidu.com/data/inner?tn=reserved_all_res_tn&type=json&resource_id=52109&apiType=yearMonthData&query=2023年12月