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)

输出格式可以自行处理,爬取数据时还是先去看一下网页上格式是什么样的,每年的地址不一样,内容不一样,读取方法也需要调整,本文只做当前的一个学习记录,希望对大家有所帮助。

  • 8
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值