爬取携程网机票价格并提供搜索功能

来源:互联网 发布:手机量长度软件 编辑:程序博客网 时间:2024/04/29 00:55

要爬取的数据是最近一段时间的飞机航班的最低价,并提供搜索功能。
利用谷歌浏览器的检查来获取最近一段时间飞机航班最低价json数据的url。
这里写图片描述
打开之后:
这里写图片描述
注意这里我们并不能用json模块将数据转换为json格式。如果转换为json格式会造成:

不能获取价格,日期是变化的,因此如果要用text.get('Prices').get('date')获取价格是不可能的。

那么只能用正则表达式分别匹配日期和价格,构造键值对,日期为键,价格为值:

'''    L获取日期,L2获取价格。价格在匹配时会把2017以及2018也匹配到,因此删掉    '''    L = re.findall(r'[0-9]{4}\-[0-9]{2}\-[0-9]{2}', lowerprice_html)    L1 = re.findall(r'\d{3,4}', lowerprice_html)    L2 = []    min = 500    '''    设置一个最小价格    '''    for i in range(len(L1)):        if int(L1[i]) == 2017 or int(L1[i]) == 2018:            pass        else:            L2.append(L1[i])    '''    构造键值对    '''    for i in range(len(L)):        InsertDict(D2, L[i], L2[i])    '''    爬取的价格与min值进行比较,如果比min的值小,更新min的值    '''    for k in D2:        if int(D2[k]) < int(min):            min = D2[k]        else:            pass    '''    获取日期    '''    for k in D2:        if D2[k] == min:            print('最低票价为: %s 日期为: %s' %(D2[k], k))            return k

这样便获取了最低票价以及日期。
如何提供搜索功能?
观察存放最低票价json数据的url:
http://flights.ctrip.com/domestic/ajax/Get90DaysLowestPrice?dcity=WUH&acity=BJS&ddate=2017-10-26&searchType=S&isDirect=T&r=0.8178801383025491
可以看到出发地武汉被编码成了WUH并赋值给了dcity,目的地北京被编码成了BJS并赋值给了acity,日期被赋值给了ddate。
如果想要提供搜索功能,把想要搜索的行程的出发地,目的地,日期分别赋值给dcity,acity,ddate。
但是携程网对城市缩写有它自己的命名方式。比如北京的缩写被命名了BSJ,武汉的缩写被命名了WUH。并不是简单地对拼音进行缩写。
幸运的是,携程网对于每个城市以及携程自己定义的城市名缩写都放在了一个js文件中。
这里写图片描述
打开文件:
这里写图片描述
看着挺像json格式,其实并不是。因此要用正则表达式把城市名以及城市名缩写(如北京(BJS)提取出来:

s = re.findall(r'[\u4e00-\u9fa5]+\([A-Z]+\)', citycode_html)'''    举个例子,例如北京(BJS)    字符串替代功能    s0 = ['北京', 'BJS)']    s1 = '北京'    s2 = 'BJS'    s1为键,s2为值构建字典    '''    for i in range(len(s)):        s0 = s[i].split('(')        s1 = s0[0]        s2 = s0[1].replace(')', '')        Insertict(D1, s1, s2)

这样就把城市名以及城市名缩写构造成了字典,方便进行搜索。

def GetCitycode(original_city, D):    for k in D:        if original_city == k:            return D[k]        else:            pass

搜索完成后,就要拼接url了,把dcity,acity,ddate换成我们想要搜索的城市的缩写以及日期就行了。

import reimport urllib.requestimport jsondef InsertDict(D, key, value):    D.setdefault(key)    D[key] = valuedef GetHtml(url):    response = urllib.request.urlopen(url)    text = response.read().decode('gbk')    return textdef GetDict(s, D1):    for i in range(len(s)):        s0 = s[i].split('(')        s1 = s0[0]        s2 = s0[1].replace(')', '')        InsertDict(D1, s1, s2)def GetCitycode(original_city, D):    for k in D:        if original_city == k:            return D[k]        else:            passdef UrlJoin(original_city_code, target_city_code, t):    return 'http://flights.ctrip.com/domestic/ajax/Get90DaysLowestPrice?dcity=%s&acity=%s&ddate=%s&searchType=S&r=0.18035678380179632' % (original_city_code, target_city_code, t)def GetLowestprice(lowerprice_html, D2):    data = json.loads(lowerprice_html)    L = re.findall(r'[0-9]{4}\-[0-9]{2}\-[0-9]{2}', lowerprice_html)    L1 = re.findall(r'\d{3,4}', lowerprice_html)    L2 = []    min = 1500    for i in range(len(L1)):        if int(L1[i]) == 2017 or int(L1[i]) == 2018:            pass        else:            L2.append(L1[i])    for i in range(len(L)):        InsertDict(D2, L[i], L2[i])    for k in D2:        if int(D2[k]) < int(min):            min = D2[k]        else:            pass    for k in D2:        if D2[k] == min:            print('最低票价为: %s 日期为: %s' %(D2[k], k))            return kD1 = {}D2 = {}get_citycode_url = 'http://webresource.c-ctrip.com/code/cquery/resource/address/flight/flight_new_poi_gb2312.js?releaseno=?CR_2016_03_07_22_18_26'citycode_html = GetHtml(get_citycode_url)s = re.findall(r'[\u4e00-\u9fa5]+\([A-Z]+\)', citycode_html)GetDict(s, D1)original_city = input('请输入出发地:')target_city = input('请输入目的地:')t = input('请输入时间:')original_city_code = GetCitycode(original_city, D1)target_city_code = GetCitycode(target_city, D1)get_lowerprice_url = UrlJoin(original_city_code, target_city_code, t)print(get_lowerprice_url)lowerprice_html = GetHtml(get_lowerprice_url)k = GetLowestprice(lowerprice_html, D2)target_url = 'http://flights.ctrip.com/booking/%s-%s-day-1.html?DDate1=%s' % (original_city_code, target_city_code, k)print(target_url)

运行结果:

请输入出发地:上海请输入目的地:北京请输入时间:2017-10-26http://flights.ctrip.com/domestic/ajax/Get90DaysLowestPrice?dcity=SHA&acity=BJS&ddate=2017-10-26&searchType=S&r=0.18035678380179632最低票价为: 250 日期为: 2017-12-02http://flights.ctrip.com/booking/SHA-BJS-day-1.html?DDate1=2017-12-02

对于拼接完的url,我们可以利用Selenium库进行打开。有些可能会搜索不到,并且数据变化的比较快,所以当看到网页上的价钱不一样时也不要惊讶。

阅读全文
0 0