大数据基础数据之中国法定节假日API

本文介绍了如何通过API获取1990年至2050年的中国法定节假日信息,包括使用开源工具箱提供的API来获取特定日期的节假日状态。同时,分享了两个Python脚本,一个用于解析JSON数据,另一个则用于定期更新数据到Hadoop或Impala数据库。这两个脚本分别实现了对节假日数据的获取、解析和入库操作,对于需要处理节假日数据的场景非常有用。
摘要由CSDN通过智能技术生成

中国法定节假日API

Date: November 16, 2021

1.背景

目前业务需求中,需要分析法定节假日。我们日常查看法定节假日,都是在百度或者某些日历中查看。但是,网上很少有通过API获得节假日的方法。因此,就自己查找资料,整理了一套脚本,获取相关节假日。

2.相关资料查找

能够获取1990年至2050年法定节假日:https://blog.csdn.net/nayi_224/article/details/109068470

百度万年历OPENAPI(只能获取2020年之前的,后面收费了): https://blog.csdn.net/flyingLF/article/details/106426427

开源工具箱 ( https://tool.bitefu.net/

其节假日API: https://www.kancloud.cn/xiaoggvip/holiday_vip/1606900

开源工具箱的API比较可靠,可以日常使用,使用方式如下:

API地址:http://tool.bitefu.net/jiari/
请求方式:GET
请求参数:d (日期/年月/年份)
返回参数:请求一天,返回对应节假日状态(0-工作日, 1-休息日, 2-节假日)
请求示例:

1.获取某一天的节假日状态:http://tool.bitefu.net/jiari/?d=20111001
	返回结果: 2
2.获取某月的节假日:http://tool.bitefu.net/jiari/?d=202110
	返回结果: {"202110":{"1001":2,"1002":2,"1003":2,"1004":1,"1005":1,"1006":1,"1007":1}}
2.获取多月的节假日:http://tool.bitefu.net/jiari/?d=202110,202111
	返回结果: {"202110":{"1001":2,"1002":2,"1003":2,"1004":1,"1005":1,"1006":1,"1007":1},"202111":false}
3.获取某年的节假日:http://tool.bitefu.net/jiari/?d=2010
	返回结果: 与月的接口类似

3.相关脚本开发

3.1 解析json数据脚本

以下脚本内容,通过开源 REST API,对结果进行json解析,得到节假日数据。

# -*- coding: utf-8 -*-

#python 代码解析法定节假日json

#导入请求包
import requests
#导入json包
import json
#导入系统包
import sys

def get_state_legal_holiday(cur_year,file_path):
    DATE_URL="https://tool.bitefu.net/jiari/?d=%s" % (cur_year)
    result=requests.get(DATE_URL)
    if result.status_code != 200 :
        sys.exit(-1)  #报错退出
    else:
        dict_data=result.json()
        for year_key in dict_data.keys():
            dict_days=dict_data.get(year_key)  #根据key,获取对应的节假日
            if dict_days == False:   # false 的情况数据无法获取
                print("===>当前年份 【%s】数据不存在,跳过" % year_key)
                continue
            else :
                print("===>当前年份 【%s】数据存在,详细数据如下:%s " % (year_key,dict_days) )
                for day_key in dict_days.keys():
                    day_status=dict_days.get(day_key) #节假日状态: 0-工作日, 1-休息日, 2-节假日,这里获取的休日实际是调休的节假日
                    day_res=(str(year_key)+day_key ) +',' + str(year_key)+',' + str(day_status) + '\n'
                    with open(file_path,'a',encoding='utf-8') as file:
                        file.write(day_res)         #csv对应字段: f_date_id,f_year_id,f_status

def main():
    if(len(sys.argv)<3):  #参数不足,默认参数是脚本本身,传参下标从1开始
        print('USAGE ERROR,PLEASE USE LIKE THIS: PYTH_SCRIPT_PATH START_YEAR END_YEAR [RESULT_FILE_PATH]' )
        sys.exit(-1)
    elif(len(sys.argv)==3):  # 传递2个参数,start_year,end_year
        start_year=int(sys.argv[1])
        end_year=int(sys.argv[2])
        result_file_path="./state_holiday.csv"

    else:  #传递3个参数,start_year,end_year,result_file_path
        start_year=int(sys.argv[1])
        end_year=int(sys.argv[2])
        result_file_path=sys.argv[3]

    print("===>相关参数:起始年份(包含):%s ,截至年份(包含):%s ,数据存储路径:%s " % (str(start_year),str(end_year),result_file_path))

    for cur_year in range(start_year,end_year+1):
        print('====> cur_year=%s' % str(cur_year))
        get_state_legal_holiday(cur_year,result_file_path)

if __name__ == '__main__' :
    main()

3.2 数据更新的脚本

以下脚本,T+1 执行,调用JSON解析脚本,获得结果数据,并写入对应表中。

#!/bin/bash

##国家法定节假日查询更新

export HADOOP_USER_NAME=bigdata

if [ $# -eq 0 ]; then
    current_year=$(date  +'%Y')
    begin_year=${current_year}
    end_year=${current_year}
elif [ $# -eq 1 ]; then
    begin_year=$1
    end_year=$1
elif [ $# -eq 2 ]; then
    begin_year=$1
    end_year=$2
else
    echo "USAGE: $0 begin_year end_year"
    exit 0
fi

CUR_TIMESTAMP=$(date +'%s')

#命令配置
BEELINE_CMD="beeline -u jdbc:hive2://node01:10000 -n bigdata "
IMPALA_CMD="impala-shell -i node02:25003 -u bigdata "

WORK_DIR=$PWD/dwd_risk_data_day_flow

#数据HIVE存在状态(默认为0,不存在)
CHECK_STATUS=0

#查验hive中是否存在该年度数据
function check_year_data_exist(){
CUR_YEAR=$1
CHECK_SQL="SELECT COUNT(*) CNT FROM dw.dim_state_legal_holiday where f_year_id='${CUR_YEAR}'  ;"
YEAR_DATA_CNT=$( $IMPALA_CMD -B -q "${CHECK_SQL}"  )

if [ $? -ne 0 ];then echo "there is an error!" ; exit 1 ; fi

if [ ${YEAR_DATA_CNT} -gt 0 ];then
    echo "===>当前年度【${CUR_YEAR}】的节假日数据已存在,为防请求过多导致IP拦截,不进行请求"
    CHECK_STATUS=1
else
    CHECK_STATUS=0
fi

}

function update_holiday_data(){

cur_year="$1"

RESULT_FILE="state_holiday-${cur_year}.csv"
RESULT_PATH=$WORK_DIR/$RESULT_FILE
HDFS_LOAD_PATH="/tmp/bigdata/${RESULT_FILE}"

/opt/anaconda3/bin/python ${WORK_DIR}/state_legal_holiday_parse.py ${cur_year} ${cur_year} "${RESULT_PATH}"

if [ $? -ne 0 ];then echo "there is an error!" ; exit 1 ; fi

hdfs dfs -rm -f ${HDFS_LOAD_PATH}

hdfs dfs -put ${RESULT_PATH} ${HDFS_LOAD_PATH}

LOAD_DATA_SQL="LOAD DATA INPATH '${HDFS_LOAD_PATH}' OVERWRITE INTO TABLE tmp.dim_state_legal_holiday ; "

$BEELINE_CMD -e "${LOAD_DATA_SQL}"

if [ $? -ne 0 ];then echo "there is an error!" ; exit 1 ; fi

UPDATE_DATA_SQL="
REFRESH tmp.dim_state_legal_holiday ;
REFRESH dw.dim_state_legal_holiday ;
INSERT OVERWRITE TABLE dw.dim_state_legal_holiday
select
f_date_id,
f_year_id,
f_status
from
    (
    SELECT
    f_date_id,
    f_year_id,
    f_status,
    row_number() over(partition by f_date_id order by f_date_id ) rank
    FROM
        (
        --增量数据
        select
        f_date_id,
        f_year_id,
        f_status
        from tmp.dim_state_legal_holiday
        union all
        --原有数据
        select
        f_date_id,
        f_year_id,
        f_status
        from dw.dim_state_legal_holiday
        ) t
    ) p
where rank=1
;
"

$IMPALA_CMD -q "${UPDATE_DATA_SQL}"

if [ $? -ne 0 ];then echo "there is an error!" ; exit 1 ; fi

}

function main(){

for((cur_year=${begin_year};cur_year<=${end_year};cur_year++));
do
    check_year_data_exist ${cur_year}

    if [ ${CHECK_STATUS} -eq 1 ];then
        continue
    fi

    update_holiday_data ${cur_year}

done

}

main

exit 0

如有用处,烦请点赞收藏^_^

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值