Python实现节假日数据获取
本篇主要内容为通过爬取国务院放假安排,来获取当年所有的假期数据。
文章目录
一、Holidays
只获取法定节假日的话,用holidays库是最简单最方便的:
import holidays
def getLegalHolidays(year): # 获取法定节假日,不包含周末
cn_holidays = holidays.CountryHoliday('CN', None, [year])
for item in cn_holidays.keys():
print(item)
if __name__ == '__main__':
# 调用函数并输出结果
getLegalHolidays(2024)
输出格式如下:
这里就是只有法定节日的放假的日期,不包含周末,也不会有调休上班的数据,如果需要更详细的假期数据,最靠谱的就是去读国务院的假期安排,如下。
二、读取国务院法定节假日安排
先确定要爬取的节假日安排的地址,f12看看需要的数据在哪里,解析出来,我个人是觉得用p标签这样的查找方式比较方便。
import requests
from bs4 import BeautifulSoup #解析网页
def getOfficialHolidays(year): #获取国务院节假日安排,包括调休
url = "https://www.gov.cn/zhengce/content/202310/content_6911527.htm" #2024年放假安排url
rep = requests.get(url) # Get方式获取网页数据
rep.encoding = 'utf-8'
soup = BeautifulSoup(rep.text, 'html.parser')
pList = soup.find_all('p')
for item in pList:
p = item.text
if ':' in p and '放假' in p: #找出节日对应的几行内容
print(p)
if __name__ == '__main__':
getOfficialHolidays(2024)
输出内容如下:
接下来就是处理这些内容,获取出来放假的日期和需要上班的日期。我是使用这些关键字去截取读取需要的数据,感觉挺繁琐,后续有时间再看怎么优化:
import datetime
legal_hols = [] #法定节假日
legal_works = [] #法定调休上班日期
def getOfficialHolidays(year): #获取国务院节假日安排,包括调休
... #接上面代码
if ':' in p and '放假' in p: #找出节日对应的几行内容
#print(p)
holidayStr = p.split(":")[1]
holidayArranges = holidayStr.split('。')
for holItem in holidayArranges:
if '上班' in holItem: #调休上班安排
workDayStr = holItem.replace('(星期六)','').replace('(星期日)','').replace('上班', '')
workDays = workDayStr.split('、')
for workDayItem in workDays:
workDay = workDayItem.replace('月', '-').replace('日', '')
workDate = datetime.date(year=year, month=int(workDay.split('-')[0]), day=int(workDay.split('-')[1]))
legal_works.append(workDate)
# print(workDayStr)
if '放假' in holItem: #放假安排
dayStr = holItem.split('放假')[0].replace('日', '')
# print(dayStr)
if '至' in dayStr:
dayItems = dayStr.split('至')
startDate = dayItems[0]
month = int(startDate.split('月')[0])
startDay = int(startDate.split('月')[1])
endDay = int(dayItems[1])
for i in range(startDay, endDay+1):
holDate = datetime.date(year=year, month=month, day=i)
legal_hols.append(holDate)
else:
monthDay = dayStr.replace('月', '-')
holDate = datetime.date(year=year, month=int(monthDay.split('-')[0]), day=int(monthDay.split('-')[1]))
legal_hols.append(holDate)
legal_hols为法定节假日的数组,legal_works是法定调休上班的日期数组,main方法可以直接打印出来看。
三、获取所有周末
如果想要获取某年所有的假期,可以结合上面打印出来的legal_hols和legal_works,周末加上法定假期,再去掉调休后需要上班的日期:
def get_all_weekends(year):
weekend_dates = []
# 设置起始日期为指定年份的第一天
start_date = datetime.date(year=year, month=1, day=1)
while True:
if start_date.isoweekday() == 6 or start_date.isoweekday() == 7:
weekend_dates.append(start_date)
# 判断当前日期是否已经超过了该年最后一天
if start_date >= datetime.date(year=year, month=12, day=31):
break
# 将日期加上一天
start_date += datetime.timedelta(days=1)
return weekend_dates
if __name__ == '__main__':
result = get_all_weekends(2024) #所有的周末
for add in legal_hols:
result.append(add) #增加非周末的法定假期安排
result = list(set(result)) #去重
for ref in legal_works:
result.remove(ref) #去掉法定需要调休上班的假期
new_res = sorted(result) #排序
for date in new_res:
dateStr = date.strftime('%Y-%m-%d')
print(dateStr)
输出格式可以自行处理,爬取数据时还是先去看一下网页上格式是什么样的,每年的地址不一样,内容不一样,读取方法也需要调整,本文只做当前的一个学习记录,希望对大家有所帮助。