之前做过一个小的需求 需要每年最后一个月更新出明年的所有休息日和节假日,包括具体的时间
上图所展示的便是结果
因为python calendar可以获得节假日的具体时间和日期 但是显示出来的文本却是英文,并且不能够确定调休假等等这种,所以需要使用python爬取百度的日历数据,并且结合calendar库 和 翻译库进行出来
话不多说 直接上代码
需要声明一点 就是我们在使用翻译库的时候 个人建议使用pygtans这个库会好点,因为会翻译的更为准确一点 比如National Day为国庆节但是 translate库会翻译错误 亲测
# 导入所需要的库
import holidays
import datetime
import requests
import json
import pandas as pd
from translate import Translator
from pygtrans import Translate
holidays_ = holidays.CN(years=2023)
print(holidays_)
chinese = []
for i in holidays_.values():
if '(' in i:
i = i.split('(')[1].split(')')[0]
chinese.append(i)
else:
chinese.append(i)
legal_holiday = []
chinese_ = []
for y in chinese:
chinese_.append(Translate().translate(y).translatedText)
for i in holidays_.keys():
legal_holiday.append(i)
dict_ = {}
for i in range(len(legal_holiday)):
dict_[legal_holiday[i]] = chinese_[i]
print(dict_)
# 从百度的php接口中获取到数据
def catch_url_from_baidu(calcultaion_year, month):
headers = {
"Content-Type": "application/json;charset=UTF-8"
}
param = {
"query": calcultaion_year + "年" + month + "月",
"resource_id": "39043",
"t": "1604395059555",
"ie": "utf8",
"oe": "gbk",
"format": "json",
"tn": "wisetpl",
"cb": ""
}
# 抓取位置:百度搜索框搜索日历,上面的日历的接口,可以在页面上进行核对
r = requests.get(url="https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php",
headers=headers, params=param).text
# print(r)
month_data = json.loads(r)["data"][0]["almanac"]
not_work_day = []
for one in month_data:
if (one["cnDay"] == '日' or one["cnDay"] == '六'):
if ('status' in one):
if (one["status"] == "2"):
# status为2的时候表示周末的工作日,百度日历上会有班标志的数据
continue
else:
# 普通周末时间
not_work_day.append(one)
continue
else:
# 普通周末时间。(接口中,如果左上角没有特殊表示,则不会返回status)
not_work_day.append(one)
continue
if ('status' in one and one["status"] == "1"):
# status为1的时候表示休息日,百度日历上会有休标志的数据
not_work_day.append(one)
a = print_info(not_work_day)
return a
# print_info(not_work_day)
def print_info(not_work_day):
date_ = []
for one in not_work_day:
template_ = f"({one['year']},{one['month']},{one['day']})"
date_.append(template_)
return date_
if __name__ == '__main__':
calcultaion_year = "2023"
# 因该接口传入的时间,查询了前一个月,当前月和后一个月的数据,所以只需要2、5、8、11即可全部获取到。比如查询5月份,则会查询4,5,6月分的数据
calculation_month = ["2", "5", "8", "11"]
date_ = []
for one_month in calculation_month:
date_.append(catch_url_from_baidu(calcultaion_year, one_month))
def sum_list(arg):
return sum(arg, [])
date_ = sum_list(date_)
# date_ = [y for y in i for i in date_]
time_ = []
for i in date_:
i = i.replace('(','')
i = i.replace(')','')
i = list(map(int, i.split(',')))
time_.append(datetime.date(i[0],i[1],i[2]))
df = pd.DataFrame(time_, columns=['时间'])
def cer_(x):
if x in legal_holiday:
return dict_[x]
else:
return '休息日'
df['类别'] = df['时间'].apply(cer_)
df.to_excel('日历数据.xlsx',index=False)
输出结果
上面所说的状态 指的就是这个左上角的 班 和 休字的日期和时间 如有更好的方法 欢迎讨论