从表格E列里读取出阳历或者农历日期数据,全部转变为阳历日期写入到F列,如果是农历日期通过下面网站进行查询后,将阳历结果写进相应农历日期对应的表格中,样式如下:
网站:https://gonglinongli.51240.com/
G列为了按日期排序方便才加的;E列日期格式固定不变;D列如果是阳历或者为空也按阳历,则直接写入到后面单元格中; 如果是农历经过以上网站的查询,将查询结果返回并自动写入到后面相应单元格中。
#!/usr/bin/env python
# coding=utf-8
# https://gonglinongli.51240.com/
from openpyxl import load_workbook
from xlrd import xldate_as_tuple
import requests
from bs4 import BeautifulSoup
import re
from openpyxl.styles import Font, Alignment
class Calendar(object):
def __init__(self):
# 正则规则,获取网站查询结果value后面的年月日数字
self.pattern = re.compile(r'value="(.+?)"')
# 调取的网址
self.url = "https://gonglinongli.51240.com/"
self.headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Referer": "https://gonglinongli.51240.com/",
}
self.file_name = '员工信息(生日表).xlsx'
try:
self.wb = load_workbook(self.file_name)
self.ws = self.wb.worksheets[0]
# 增加第七列,便于筛选,写成2018/5/6
self.ws.cell(row=1, column=7).value = '阳历简写'
# 设置第一行第七列,字体、大小、加粗,水平、垂直居中
self.ws.cell(row=1, column=7).font = Font(name='微软雅黑', size=11, bold=True)
self.ws.cell(row=1, column=7).alignment = Alignment(horizontal='center', vertical='center')
# 如果没有这个EXCEL表或者名字不符合要求,则提示
except:
print('没有此文件或文件名不符合要求,应为:"%s"' % self.file_name)
exit()
# 调取excel表格数据
def main(self):
for row in range(2, self.ws.max_row + 1):
# 设置从第二行第七列开始,单元格格式为日期格式,字体、大小,水平、垂直居中
self.ws.cell(row=row, column=7).number_format = 'yyyy/mm/dd'
self.ws.cell(row=row, column=7).font = Font(name='微软雅黑', size=10, bold=False)
self.ws.cell(row=row, column=7).alignment = Alignment(horizontal='center', vertical='center')
try:
print("第%s行数据处理中……" % row)
# 结果是元组,类似于(2018, 12, 2, 0, 0, 0)
data_tuple = xldate_as_tuple(self.ws.cell(row=row, column=5).value, 0)
# 如果第四列单元格是阳历或者是空,空的话默认为阳历,去掉首尾空格来判断,None要写在判断语句第一位?
fourth_col_value = self.ws.cell(row=row, column=4).value
if (fourth_col_value) == None or (fourth_col_value).strip() == '阳历' or (fourth_col_value).strip() == "":
# 判断阳历的年份是否符合要求
if int(data_tuple[0]) in range(1901, 2100):
# 将结果转变为2018年12月2日
data = str(data_tuple[0]) + '年' + str(data_tuple[1]) + '月' + str(data_tuple[2]) + '日'
# 如果是阳历将转换后的结果直接写进第六列
self.ws.cell(row=row, column=6).value = data
# 增加第七列,便于筛选写成2018/5/6样式
data_seven = str(data_tuple[0]) + '/' + str(data_tuple[1]) + '/' + str(data_tuple[2])
self.ws.cell(row=row, column=7).value = data_seven
else:
# 如果不符合要求,相应行的第六列单元格中不能有值
self.ws.cell(row=row, column=6).value = None
# 如果不符合要求,相应行的第七列单元格中不能有值
self.ws.cell(row=row, column=7).value = None
print("单元格'E%s'数据有误,请输入1901-2099年内任意年份!不能是%s年" % (row, data_tuple[0]))
# 如果第四列单元格是农历,去掉首尾空格
elif (self.ws.cell(row=row, column=4).value).strip() == '农历':
nongli_nian = str(data_tuple[0])
nongli_yue = str(data_tuple[1])
nongli_ri = str(data_tuple[2])
if (data_tuple[0]) in range(1901, 2100):
# 是农历的话调取judge_date函数,并传入年月日及行数的参数
i, j, k, row_ = calendar.judge_date(nongli_nian, nongli_yue, nongli_ri, row)
# 返回并拼接转换成阳历后的数据
result_data = i + '年' + j + '月' + k + '日'
# 将上述转换成阳历后数据写入到相应农历日期对应的第六列单元格中
self.ws.cell(row=row_, column=6).value = result_data
# 将上述转换成阳历后数据写入到相应农历日期对应的第七列单元格中
result_data_seven = i + '/' + j + '/' + k
self.ws.cell(row=row_, column=7).value = result_data_seven
else:
# 如果不符合要求,相应行的第六列单元格中不能有值
self.ws.cell(row=row, column=6).value = None
# 如果不符合要求,相应行的第七列单元格中不能有值
self.ws.cell(row=row, column=7).value = None
print("单元格'E%s'输入有误,请输入1901-2099年内任意年份!不能是%s年" % (row, nongli_nian))
else:
# 如果不符合要求,相应行的第六列单元格中不能有值
self.ws.cell(row=row, column=6).value = None
self.ws.cell(row=row, column=7).value = None
print('*************问题线*****************')
print("单元格'D%s'输入有误,只能填写阳历、农历或者为空,为空则默认为阳历" % row)
except:
# 如果不符合要求,相应行的第六列单元格中不能有值
self.ws.cell(row=row, column=6).value = None
self.ws.cell(row=row, column=7).value = None
print('*************问题线*****************')
print("单元格'E%s'数据有问题,请核实!" % row)
try:
self.wb.save(self.file_name)
print("数据处理完毕,谢谢使用!")
except:
print("表格未保存,请关闭'%s'表格,再重新执行一次!" % self.file_name)
# 判断用户输入的年月日是否符合要求,这个网站1-9要转变为01-09
def judge_date(self, nongli_nian, nongli_yue, nongli_ri, row):
if int(nongli_nian) in range(1901, 2100):
self.nongli_nian = nongli_nian
# 因为excel表格的E列已经限制为日期格式,所以月份和日不会写错,如果是用户输入的则判断,查看另一篇文章有介绍
# 另一篇文章地址:
if int(nongli_yue) in range(1, 13):
self.nongli_yue = calendar.judge_yue(nongli_yue)
if int(nongli_ri) in range(1, 31):
self.nongli_ri = calendar.judge_ri(nongli_ri)
self.formdata = {
"nongli_nian": self.nongli_nian,
"nongli_yue": self.nongli_yue,
"nongli_ri": self.nongli_ri,
}
return calendar.write_data(row)
# 处理传过来的农历月中1-9转换为01-09
def judge_yue(self, nongliyue):
# 如果传过来的值第一位不是0并且是一位数,前面就要加0
if nongliyue[0] != '0' and len(nongliyue) == 1:
nongli_yue = '0' + str(nongliyue)
return nongli_yue
else:
return nongliyue
# 处理传过来的农历日中1-9转换为01-09
def judge_ri(self, nongliri):
# 如果传过来的农历日值第一位不是0并且是一位数,前面就要加0
if nongliri[0] != '0' and len(nongliri) == 1:
nongli_ri = '0' + str(nongliri)
return nongli_ri
else:
return nongliri
def write_data(self, row):
items = []
response = requests.post(self.url, data=self.formdata, headers=self.headers)
soup = BeautifulSoup(response.text, 'lxml')
# 查找返回页面的所有包含script标签的内容,形成一个列表
script_list = soup.select('script')
for i in script_list:
# 获取所有包含script标签的内容,并放到items列表里
script_text = i.get_text()
items.append(script_text)
# 在items列表里找出包含‘document.getElementById’字段的内容,这个字段包含想要的结果
for j in items:
if 'document.getElementById' in j and 'getElementById("gongli_yue").value' in j:
result = self.pattern.findall(j)
# print('\n'+"农历:%s年%s月%s日,转为阳历为:%s年%s月%s日"%(result[3],self.nongli_yue,result[5],
# result[0],result[1],result[2]))
return result[0], result[1], result[2], row
if 'document.getElementById' in j and 'getElementById("gongli_yue").value' not in j:
# print('*************问题线*****************')
# 如果不符合要求,相应行的第六列单元格中不能有值
self.ws.cell(row=row, column=6).value = None
self.ws.cell(row=row, column=7).value = None
print('网站返回结果:单元格"E%s"输入的农历日期不正确,请仔细核对。' % row)
# print('单元格"E%s"的农历日期为:%s年%s月%s日'%(row,self.nongli_nian,self.nongli_yue,self.nongli_ri))
if __name__ == "__main__":
calendar = Calendar()
calendar.main()