利用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 = ['xxxxx@qq.com']
    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)

创作不易,喜欢的话给喵喵赏点吧~(可怜眼神)
在这里插入图片描述

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值