Article | carefree huan \

Source: Python Technology “ID: pythonall”

I decided to get the certificate with my girlfriend. I couldn’t tell you how excited I was! Both of us are more casual, ready to get hukou this book to get.

But who knows girlfriend comes home to take account of this of time, say with me: recently may not get!

What? Ducks in a row? My heart gave a heave.

Ask after just know, mother-in-law say get certificate can, but want to choose a auspicious day, ask to have two: one is to see calendar, choose appropriate “marriage leave” day; One is the need to choose even numbers in the lunar calendar, which represent good luck.

After hearing that, I patted my chest and said no problem. Then prepare to turn over the calendar, can not want to this time girlfriend to 1: you a fool, but also prepare a day to turn over? Doesn’t it take a second to write a small program?

I patted head, rightness, still wife cleverness! Don’t say a word, open the computer to open dry.

Ideas and Implementation

I in Baidu input box input “calendar” query, pop up the first of course is Baidu’s own calendar cough up, but I do not want to spend time on Baidu, because the time is tight, heavy task, I choose a relatively easy.

The site seems to be informative and not one of the big hot sites, so it should be relatively easy to get information. \

The home page is also quite clear, I need several big information (calendar, lunar date, almanac). \

Next, let’s look at page requests to locate requests for information we need.

I found in this page is not more request the request (staticwnl.tianqistatic.com/Public/Home…

This seems to be our target request. Let’s look at the return: \

Very good, they returned a year’s data at once, it feels so easy, we don’t have to ask every day. \

I took a closer look at the return and realized it wasn’t that simple. I couldn’t find the lunar date:

{
  "y": [
    "Sacrifice"."Plastic paint"."Medallion"."Cloth"."Crown Ji"."Marry"."Mining"."Remove"."Build"."Stick"."Vertical column"."Liang"."Bed" Ann."Migration"."Into the house"."AnXiang"."Netting"."Capture"."Tian hunting"."Logging"."Incoming population"."Water"]."j": [
    "Travel"."Funeral"."Repair grave"."Open"]."ts""Occupy room bed inside room north."."c""Rush pig"."s""Very east"."zc""Ding hai"."zh""Hold"."yq""Five rich After benefit"."yj""A small loss, a day, a day, and a sword."
}
Copy the code

I put my innocence aside and started looking for ways to get lunar dates. I didn’t find a request to get a lunar date, but I did find a special request:

This request does not get the lunar date directly, but is calculated in JavaScript. We can see the calculation method in this request:

/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = calculate the lunar calendar, the incoming date controls, control returns to the lunar calendar date
// The control has properties.year.month.day. IsLeap
//sDObj = new Date(y,m,i+1); Date of the first day of the month
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); // Leap which month
    this.isLeap = false;
    for (i = 1; i < 13 && offset > 0; i++) {
        / / leap month
        if (leap > 0 && i == (leap + 1) && this.isLeap == false) {
            --i;
            this.isLeap = true;
            temp = leapDays(this.year);
        } else {
            temp = monthDays(this.year, i);
        }
        // Remove leap months
        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;
}
Copy the code

Of course, there are many other methods in this JS file, such as calculating days, holidays and so on. We can implement this js method in Python to calculate lunar dates and holidays and so on. But MY time is more pressing, so I choose to use the simplest way – Baidu. Baidu will be written by others inside the method directly used, do not have to repeat the wheel.

Search can find many ways to calculate calendar information, I selected one as a tool class to use.

Now that we’ve done the prelude, we’re ready to go, so let’s look at the code.

The first step is to get information for each day of a given year:


def get_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, ' ')
    if cur_year == year:
        jsonstr = jsonstr.replace(cur_end_str, ' ')
    else:
        jsonstr = jsonstr.replace(his_end_str, ' ')

    return jsonstr
    
Copy the code

Note that string interference is added before and after the JSON data. We need to remove these strings to parse JSON.

You think this is the end of it? Did you find that you can’t parse the data for 2020 the same way you parse the data for 2021? You read that right, here the website developers have made a little joke, they have changed a semicolon in the end of the string. According to my careful observation, this semicolon is at the end of the return results for the current year, while in the return data for other years, this semicolon is inside curly braces.

After obtaining the data, we calculate the date:


def choose_day(year, jsonstr):
    jobj = json.loads(jsonstr)
    for day in jobj.keys():
        y = jobj[day]['y']
        if 'to marry' in y:
            dtime = datetime.datetime(year, int(day[1:3]), int(day[3:5Get_ludar_date (dtime) = lunarUtils.get_ludar_date(dtimeif ludar_date[2] % 2= =0:
               print('Gregorian date: %s, Lunar date: %s' % (day, ludar_date))
Copy the code

This is relatively simple: first parse the returned JSON data, then walk through the date, get the information for each day, to see which day is good to “marry”, then get the date of the lunar calendar, to see if it is even, if so, this is our target date.

The last date I got was this:

Gregorian date: D0107, lunar date: (2020.11.24) Gregorian date: D0122, Lunar date: (2020.12.10) Gregorian date: D0124, Lunar date: (2020.12.12) Gregorian date: D0126, lunar date: (2020.12.14) Gregorian date: D0203, Lunar date: (2020.12.22) Gregorian date: D0209, Lunar date: (2020.12.28) Gregorian date: D0225, Lunar date: (2021.1.14) Gregorian date: D0305, Lunar date: (2021.1.22) Gregorian date: D0311, Lunar date: (2021.1.28) Gregorian date: D0318, Lunar date: (2021.2.6) Gregorian date: D0324, lunar date: (2021.2.12) Gregorian date: D0401, lunar date: (2021.2.20) Gregorian date: D0419, lunar date: (2021.3.8) Gregorian date: D0425, lunar date: (2021.3.14) Gregorian date: D0507, lunar date: (2021.3.26) Gregorian date: D0513, Lunar date: (2021.4.2) Gregorian date: D0525, Lunar date: (2021.4.14) Gregorian date: D0531, lunar date: (2021.4.20) Gregorian date: D0606, Lunar date: (2021.4.26) Gregorian date: D0613, lunar date: (2021.5.4) Gregorian date: D0617, lunar date: (2021.5.8) Gregorian date: D0619, lunar date: (2021.5.10) Gregorian date: D0625, lunar date: (2021.5.16) Gregorian date: D0701, Lunar date: (2021.5.22) Gregorian date: D0711, Lunar date: (2021.6.2) Gregorian date: D0713, Lunar date: (2021.6.4) Gregorian date: D0717, lunar date: (2021.6.8) Gregorian date: D0723, Lunar date: (2021.6.14) Gregorian date: D0725, Lunar date: (2021.6.16) Gregorian date: D0729, Lunar date: (2021.6.20) Gregorian date: D0804, lunar date: (2021.6.26) Gregorian date: D0811, Lunar date: (2021.7.4) Gregorian date: D0813, Lunar date: (2021.7.6) Gregorian date: D0815, Lunar date: (2021.7.8) Gregorian date: D0823, Lunar date: (2021.7.16) Gregorian date: D0827, Lunar date: (2021.7.20) Gregorian date: D0914, Lunar date: (2021.8.8) Gregorian date: D0926, Lunar date: (2021.8.20) Gregorian date: D1013, lunar date: (2021.9.8) Gregorian date: D1015, lunar date: (2021.9.10) Gregorian date: D1025, Lunar date: (2021.9.20) Gregorian date: D1029, lunar date: (2021.9.24) Gregorian date: D1106, Lunar date: (2021.10.2) Gregorian date: D1110, lunar date: (2021.10.6) Gregorian date: D1112, lunar date: (2021.10.8) Gregorian date: D1116, lunar date: (2021.10.12) Gregorian date: D1124, lunar date: (2021.10.20) Gregorian date: D1130, lunar date: (2021.10.26) Gregorian date: D1207, lunar date: (2021.11.4) Gregorian date: D1211, Lunar date: (2021.11.8) Gregorian date: D1219, lunar date: (2021.11.16) Gregorian date: D1223, Lunar date: (2021.11.20) Gregorian date: D1231, lunar date: (2021.11.28)
Copy the code

It is 0126 in Gregorian calendar, 1214 in lunar calendar, 12+14=26. I think it is quite good. Unfortunately, I missed it today and can only postpone it. I looked and found that if I wanted to get my license before the Chinese New Year, there were only two dates to choose. I decided to choose February 3, which coincides with the start of spring and is a good day.

conclusion

Python applications are everywhere, and our lives will be better and more efficient if we use them well. I’m about to get my license. Can you give me a thumbs up?

PS: Reply “Python” within the public number to enter the Python novice learning exchange group, together with the 100-day plan!

Old rules, brothers still remember, the lower right corner of the “watching” click, if you feel the content of the article is good, remember to share moments to let more people know!

[Code access ****]

Identify the qr code at the end of the text, reply: 210127