疯狂!领证还要写Python!!!

决定和女朋友去领证了,心里那个激动啊,无以言表!我们俩都是比较随性的,准备拿到户口本就去领。

可谁知女朋友回家拿户口本的时候,跟我说:最近可能领不了了!

what?到手的鸭子要飞了?我心里咯噔一下。

询问后才知道,丈母娘说领证可以,但是要选择一个良辰吉日,要求有俩:一个是看万年历,选取宜“婚假”的日子;一个是需要选择农历的双数日期,双数代表吉利。

听了之后,我拍着胸脯说没问题。接着准备去翻万年历了,可不想这时候女朋友来一句:你个呆子,还准备一天天地去翻啊?写个小程序不就1秒钟的事吗?

我拍了拍脑袋,对哦,还是老婆聪明!话不多说,打开电脑就开干。

思路和实现

我在百度输入框输入“万年历”查询,弹出的第一个当然是百度自己的万年历咯,但是我不想在百度上耗时间,因为时间紧,任务重,我选取一个相对容易的。

疯狂!领证还要写Python!!!

这个网站看起来信息比较全,并且不是那种热门的大网站,所以应该获取信息相对容易些。

疯狂!领证还要写Python!!!

首页也比较清晰明了,我所需要的几大信息(日历、农历日期、黄历)都有。

接着,我们来看看页面的请求,来定位我们所需信息的请求。

我在这个页面不算多的请求里面发现了这个请求(https://staticwnl.tianqistatic.com/Public/Home/js/api/yjs/2021.js):

疯狂!领证还要写Python!!!

这好像就是我们的目标请求,我们来看看返回:

疯狂!领证还要写Python!!!

非常好,人家一次性把一年的数据都返回了,感觉好简单啊,都不用咱们一天天请求了。

我再仔细看了下这个返回,发现并没有那么简单,我没找到农历的日期:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
{

"y": [

"祭祀",

"塑绘",

"开光",

"裁衣",

"冠笄",

"嫁娶",

"纳采",

"拆卸",

"修造",

"动土",

"竖柱",

"上梁",

"安床",

"移徙",

"入宅",

"安香",

"结网",

"捕捉",

"畋猎",

"伐木",

"进人口",

"放水"

],

"j": [

"出行",

"安葬",

"修坟",

"开市"

],

"ts": "占房床房内北",

"c": "冲猪",

"s": "煞东",

"zc": "丁亥",

"zh": "执",

"yq": "五富 益後",

"yj": "劫煞 小耗 复日 重日 元武"

}

我收起了天真,又开始寻找获取农历日期的方法。我没有找到获取农历日期的请求,但是我发现了一个特别的请求:

疯狂!领证还要写Python!!!

这个请求并没有直接获取农历日期,而是用 JavaScript 计算的,我们可以看到这个请求里面的计算方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//====================================== 算出农历, 传入日期控件, 返回农历日期控件

// 该控件属性有 .year .month .day .isLeap

//sDObj = new Date(y,m,i+1); 当月1日日期

function Lunar(objDate) {

var i, leap = 0, temp = 0;

var offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth(), objDate

.getDate()) - Date.UTC(1900, 0, 31)) / 86400000;

for (i = 1900; i < 2100 && offset > 0; i++) {

temp = lYearDays(i);

offset -= temp;

}

if (offset < 0) {

offset += temp;

i--;

}

this.year = i;

leap = leapMonth(i); //闰哪个月

this.isLeap = false;

for (i = 1; i < 13 && offset > 0; i++) {

//闰月

if (leap > 0 && i == (leap + 1) && this.isLeap == false) {

--i;

this.isLeap = true;

temp = leapDays(this.year);

} else {

temp = monthDays(this.year, i);

}

//解除闰月

if (this.isLeap == true && i == (leap + 1)) {

this.isLeap = false;

}

offset -= temp;

}

if (offset == 0 && leap > 0 && i == leap + 1) {

if (this.isLeap) {

this.isLeap = false;

} else {

this.isLeap = true;

--i;

}

}

if (offset < 0) {

offset += temp;

--i;

}

this.month = i;

this.day = offset + 1;

}

当然,这个 js 文件里面还有好多其他诸如计算星期、节假日之类的方法,我们可以把这个 js 里面的方法实现用 python 来实现就可以计算出农历日期以及节假日之类的信息了。但是我的时间比较紧迫,所以我选择用最简单的办法——百度。将度娘里面别人写的方法直接拿来用,就不用重复造轮子了。

搜索可以发现好多计算万年历信息的方法,我从其中选取了一个作为工具类来用。

前奏已经弄完了,接下来就好办了,我们来看看代码怎么写。

第一步是获取某一年每天的信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

defget_data(year):

url='https://staticwnl.tianqistatic.com/Public/Home/js/api/yjs/%d.js'%year

response=requests.get(url)

text=response.text

start_str='lmanac["%d"] ='%year

his_end_str=';if(typeof(lmanac_2345)!="undefined"){lmanac_2345();}'

cur_end_str=';if(typeof(lmanac_2345)!="undefined"){lmanac_2345()};'

cur_year=datetime.datetime.now().year

jsonstr=text.replace(start_str,'')

ifcur_year==year:

jsonstr=jsonstr.replace(cur_end_str,'')

else:

jsonstr=jsonstr.replace(his_end_str,'')

returnjsonstr

这里需要注意的是,获取到的结果数据在 JSON 数据的前后都加了字符串干扰信息,我们需要将这些字符串给去掉才能解析 JSON。

你以为这样就完了吗?是不是发现用解析2021年的数据的方法去2020年的数据不行?你没看错,这里网站开发人员开了一个小玩笑,他们把结尾字符串里面的一个分号换了个位置。据我仔细观察发现,当年的返回结果中这个分号是在最后的,而其他年份的返回数据中这个分号是在大括号里面的。

获取到数据之后,我们就来计算日期:

1
2
3
4
5
6
7
8
9
10
11
12
13

defchoose_day(year,jsonstr):

jobj=json.loads(jsonstr)

fordayinjobj.keys():

y=jobj[day]['y']

if'嫁娶'iny:

dtime=datetime.datetime(year,int(day[1:3]),int(day[3:5]))

# 获取农历日期

ludar_date=lunarUtils.get_ludar_date(dtime)

# 取得日,然后看是否是双数

ifludar_date[2]%2==0:

print('公历日期:%s,农历日期:%s'%(day,ludar_date))

这里面就相对比较简单了,先解析返回的 JSON 数据,然后遍历日期,获取每天的信息,看哪天宜“嫁娶”,就再获取这天的农历日期,看是不是双数,如果是的话,这就是我们的目标日期。

我最后获得的日期是这样子的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
公历日期:d0107,农历日期:(2020, 11, 24)

公历日期:d0122,农历日期:(2020, 12, 10)

公历日期:d0124,农历日期:(2020, 12, 12)

公历日期:d0126,农历日期:(2020, 12, 14)

公历日期:d0203,农历日期:(2020, 12, 22)

公历日期:d0209,农历日期:(2020, 12, 28)

公历日期:d0225,农历日期:(2021, 1, 14)

公历日期:d0305,农历日期:(2021, 1, 22)

公历日期:d0311,农历日期:(2021, 1, 28)

公历日期:d0318,农历日期:(2021, 2, 6)

公历日期:d0324,农历日期:(2021, 2, 12)

公历日期:d0401,农历日期:(2021, 2, 20)

公历日期:d0419,农历日期:(2021, 3, 8)

公历日期:d0425,农历日期:(2021, 3, 14)

公历日期:d0507,农历日期:(2021, 3, 26)

公历日期:d0513,农历日期:(2021, 4, 2)

公历日期:d0525,农历日期:(2021, 4, 14)

公历日期:d0531,农历日期:(2021, 4, 20)

公历日期:d0606,农历日期:(2021, 4, 26)

公历日期:d0613,农历日期:(2021, 5, 4)

公历日期:d0617,农历日期:(2021, 5, 8)

公历日期:d0619,农历日期:(2021, 5, 10)

公历日期:d0625,农历日期:(2021, 5, 16)

公历日期:d0701,农历日期:(2021, 5, 22)

公历日期:d0711,农历日期:(2021, 6, 2)

公历日期:d0713,农历日期:(2021, 6, 4)

公历日期:d0717,农历日期:(2021, 6, 8)

公历日期:d0723,农历日期:(2021, 6, 14)

公历日期:d0725,农历日期:(2021, 6, 16)

公历日期:d0729,农历日期:(2021, 6, 20)

公历日期:d0804,农历日期:(2021, 6, 26)

公历日期:d0811,农历日期:(2021, 7, 4)

公历日期:d0813,农历日期:(2021, 7, 6)

公历日期:d0815,农历日期:(2021, 7, 8)

公历日期:d0823,农历日期:(2021, 7, 16)

公历日期:d0827,农历日期:(2021, 7, 20)

公历日期:d0914,农历日期:(2021, 8, 8)

公历日期:d0926,农历日期:(2021, 8, 20)

公历日期:d1013,农历日期:(2021, 9, 8)

公历日期:d1015,农历日期:(2021, 9, 10)

公历日期:d1025,农历日期:(2021, 9, 20)

公历日期:d1029,农历日期:(2021, 9, 24)

公历日期:d1106,农历日期:(2021, 10, 2)

公历日期:d1110,农历日期:(2021, 10, 6)

公历日期:d1112,农历日期:(2021, 10, 8)

公历日期:d1116,农历日期:(2021, 10, 12)

公历日期:d1124,农历日期:(2021, 10, 20)

公历日期:d1130,农历日期:(2021, 10, 26)

公历日期:d1207,农历日期:(2021, 11, 4)

公历日期:d1211,农历日期:(2021, 11, 8)

公历日期:d1219,农历日期:(2021, 11, 16)

公历日期:d1223,农历日期:(2021, 11, 20)

公历日期:d1231,农历日期:(2021, 11, 28)

看了一下,今天就是个好日子,公历是0126,农历是1214,12+14=26,我觉得挺好,可惜今天错过了,只能推后了。我看了一下,要赶在年前领证的话,只有两个日期可选了,我想选2月3日,这天正好立春,是个好日子。

疯狂!领证还要写Python!!!

总结

Python 应用无处不在,只要善于运用,我们的生活会更高效美好!我马上要领证了,大家可否点个赞祝福一下?

示例代码:(https://github.com/JustDoPython/python-examples/tree/master/xianhuan/lingzheng)

以上是 疯狂!领证还要写Python!!! 的全部内容, 来源链接: utcz.com/a/129470.html

回到顶部