利用python監控去哪兒網機票價格

# -*- coding: utf-8 -*-
import xml.etree.ElementTree as etree
import requests
import time
from lxml import etree
from email.mime.text import MIMEText
import smtplib


def ShowDict(d):
    print('=================')
    for v in d:
        print(v, '->', d[v])
def TripDict(d):
    for v in d:
        d[v] = d[v].strip()



# 從網上抓取票價數據,去哪兒網已經整理好放到一個xml文件,直接解析就可以了
def GetPlaneTicketPrice(FromAddr, ToAddr):
    requrl = 'http://ws.qunar.com/holidayService.jcp?lane=%s-%s' % (FromAddr, ToAddr)
    user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"
    headers = {"User-Agent": user_agent}
    request = requests.get(requrl, headers=headers)
    response = request.text.encode(encoding="utf-8")
    tree = etree.fromstring(response)

    # print(tree)
    # root = tree.getroot()
    root = tree.getiterator()
    print(type(root))



    all_info = []
    for node in root:
        cur_info = {}
        try:
            na = node.attrib
            cur_info = dict(na.items())
            #print na["date"],na['go_avc'],na['go_start'],na['go_expires']
            for child in node:
                ca = child.attrib
                item_1 = dict(cur_info.items() + ca.items())
                # print(item_1)
                item_1['from_addr'] = FromAddr
                item_1['to_addr'] = ToAddr
                item_2 = {}
                for i in item_1:
                    item_2[i.encode('utf-8')] = item_1[i] .encode('utf-8')
                all_info.append(item_2)
                #ShowDict(item_1)
        except:
            pass
    return all_info

#時間轉換函數
def GetCurrentDate():
    return time.strftime("%Y-%m-%d", time.localtime())

def GetTimeSruFromDateStr(date_str) :
    return time.strptime(date_str, "%Y-%m-%d")

def GetDateStrFromTimeSru(ti):
    return "%04d-%02d-%02d" % (ti.tm_year, ti.tm_mon, ti.tm_mday)

def GetTimeSruFromDateTimeStr(date_str):
    return time.strptime(date_str, "%Y-%m-%d %H:%M:%S")

def GetDateTimeStrFromTimeSru (ti):
    return "%04d-%02d-%02d %02d:%02d:%02d" % (ti.tm_year, ti.tm_mon,ti.tm_mday , ti.tm_hour, ti.tm_min, ti.tm_sec )

#帥選需要的字段數據和航班類型,按折扣排序
def GetTripByPrice(tp_info, trip_type='go', date_beg=None, date_end=None) :
    if not date_beg:
        date_beg = GetCurrentDate()
    if not date_end:
        date_end = date_beg

    tp = trip_type

    #過濾出需要的類型和數據類型轉換
    trip_info = []
    for v in tp_info:
        if v['type'] != trip_type:
            continue
        nv = {}
        nv['date'] = GetTimeSruFromDateStr(v['date'])
        nv['avc'] = v[tp + '_avc']
        nv['price'] = int(v['price'])
        nv['from_addr'] = v['from_addr']
        nv['to_addr'] = v['to_addr']
        #time.strptime(date_str, "%Y-%m-%d")
        ds = v['date'] + ' ' + v[tp + '_start'] + ":00"
        nv['start_time'] = GetTimeSruFromDateTimeStr(ds)
        de = v['date'] + ' ' + v[tp + '_expires'] + ":00"
        nv['expires_time'] = GetTimeSruFromDateTimeStr(de)
        dis = v['discount']
        fDis = None
        for i in dis:
            if i.isdigit():
                fDis = float(''.join([ s for s in dis if (s.isdigit() or s == '.')]))
                break
        if fDis== None:
            cc = {"全價": 10.0, "半價": 5.0, "免費": 0.0}
            fDis = cc[dis]
        nv['discount'] = fDis
        nv['name'] = v['name']
        trip_info.append(nv)

    #日期過濾
    date_beg_t = GetTimeSruFromDateStr(date_beg)
    date_end_t = GetTimeSruFromDateStr(date_end)
    trip_info = [v for v in trip_info if date_beg_t <= v['start_time'] <= date_end_t]

    #按價格排序
    sorted_tp = sorted(trip_info, key = lambda k: k['discount'])
    return sorted_tp

#根據航班列表生成網頁源碼
def MakeHtmlPage (TripList) :
    html_h = '''<html>
    <body>
    <center>
    <h4>【低價機票助手】#title#</h4>
    <table border="1" cellspacing="0" cellpadding="0" width="600" style="BORDER-COLLAPSE: collapse">
    <tr>
        <th>航班</th>
        <th>出發時間</th>
        <th>抵達時間</th>
        <th>折扣</th>
        <th>價格</th>
    </tr>'''

    html_t = '''    </table>
    </center>
    </body>
    </html>
    '''

    if not TripList:
        print('null trip found')
        return
    data_tr = ''
    from_addr = TripList[0]['from_addr' ]
    to_addr = TripList[0]['to_addr' ]
    title = '發現【%s->%s】低價機票,請注意哦!' % (from_addr, to_addr)
    html_h = html_h.replace('#title#', title)
    for v in TripList:
        cr = '    <tr>\r\n'
        ts = GetDateTimeStrFromTimeSru(v['start_time'])
        te = GetDateTimeStrFromTimeSru(v['expires_time'])
        dis = '%.1f折' % (v['discount'])
        price = '%d元' % (v['price'])
        cr = '    <tr>\r\n'
        cr += '        <th>%s</th>\r\n' % (v['avc'])
        cr += '        <th>%s</th>\r\n' % ts
        cr += '        <th>%s</th>\r\n' % te
        cr += '        <th>%s</th>\r\n' % dis
        cr += '        <th>%s</th>\r\n' % price
        cr += '    </tr>\r\n'
        data_tr += cr

    html = html_h + data_tr + html_t
    return html

#判斷郵件內容是否可以發送,統一郵件內容30分內只允許發送一次
his_msg = []
def CanSend (msg) :
    tNow = time.time()
    MinTime = 30 * 60
    bSend = True
    for i, m in enumerate(his_msg):
        if (msg == m[0]) and (tNow - m[1] < MinTime):
            bSend = False

        if tNow - m[1] > MinTime:
            del his_msg[i]

    if bSend:
        his_msg.append([msg, tNow])
    return bSend

#根據航班列表生成文本信息
def MakeEmailMsg (TripList) :
    if not TripList:
        print('null trip found')
        return
    msg = ''
    from_addr = TripList[ 0]['from_addr' ]
    to_addr = TripList[ 0]['to_addr' ]
    msg += '發現【%s->%s】低價機票,請注意哦~~\r\n' % (from_addr, to_addr)
    msg += '=' * 60 + "\r\n"
    msg += '%s\t%s\t%s\t%s\t%s\r\n' % ('航班'.center(32), '出發日期'.center(32),'航班時間' .center(40),'折扣', '價格')
    for v in TripList:
        ts = GetDateTimeStrFromTimeSru(v['start_time'])
        te = GetDateTimeStrFromTimeSru(v['expires_time'])
        di = ts[:10]
        ti = '%s->%s' % (ts[- 8:], te[-8:])
        dis = '%.1f折' % (v['discount'])
        price = '%d元' % (v['price'])
        msg += '%s\t%s\t%s\t%s\t%s\r\n' % (v['avc'], di, ti, dis, price)
    msg += '='*60 + "\r\n\r\n"
    return msg

#發送郵件,支持HTML格式和普通文本格式
def send_mail (to_list, sub,content ,ishtml=False) :
    if not CanSend(content):
        return False
    mail_host = "smtp.qq.com"# https://mail.qq.com/
    mail_user = "xxxx"
    mail_pass = "xxxxx"
    mail_postfix = "qq.com"

    me=mail_user + "<" + mail_user + "@" + mail_postfix+">"
    msg = MIMEText(content)
    if ishtml:
        msg = MIMEText(content, _subtype='html', _charset='utf-8')
    msg ['Subject'] = sub
    msg ['From'] = me
    msg ['To'] = ";".join(to_list)
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user, mail_pass)
        s.sendmail(me, to_list, msg.as_string ())
        s.close()
        print('send emial success')
        return True
    except Exception as e:
        print(str(e))
        print('send emial failed')
        return False

#監控低價航班列表,一旦發現有低折扣的機票就發送郵件
def MonitorLowTrip (FromAddr, ToAddr, DisCount=3, MaxNum=5 ):
    email_li = ['[email protected]']
    while True:
        all_info = GetPlaneTicketPrice(FromAddr, ToAddr)
        #print all_info
        LowTrip = GetTripByPrice(all_info, date_beg='2018-10-01' ,date_end= '2018-10-08')[:MaxNum]

        if LowTrip:
            if LowTrip[ 0]['discount' ] <= DisCount:
                msg = MakeHtmlPage(LowTrip) .encode('utf-8' )
                send_mail(email_li, "[低價機票]", msg, True)
                print(msg)
        else:
            print('未發現符合要求的機票')
        time.sleep(10)

if __name__ == '__main__':

    #啓動監控腳本,監控從深圳飛往寧波的機票,低於4折就把最低價的10條記錄發往郵箱
	MonitorLowTrip('深圳', '西安', 5, 10)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章