爬取携程网机票价格并提供搜索功能
来源:互联网 发布:手机量长度软件 编辑:程序博客网 时间: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库进行打开。有些可能会搜索不到,并且数据变化的比较快,所以当看到网页上的价钱不一样时也不要惊讶。
- 爬取携程网机票价格并提供搜索功能
- CentOS6安装dovecot并提供sasl功能
- 实现Scrollview嵌套ListView的功能(并提供另外解决方案)
- JAVA多服务器通讯框架-聊天功能演示程序 V0.1 alpha 发布并提供下载
- shell脚本实现查找文件夹下重复的文件,并提供删除功能
- 将附件以table列表的形式展示,并提供下载功能
- VC++界面编程之--实现一个画板并提供文字输入功能(MsPaint)
- Reveal通过视图层次帮你理解复杂的app 并提供相关Debug功能
- Struts2 遍历输出WEB-INF文件目录,并提供下载功能
- 无广告的免费视频存储空间并提供视频上传转码的功能,很不错的哦
- 从数据库读取文件并提供下载
- 动态生成.txt文件并提供下载
- 使用fileupload上传文件,并提供下载
- java输出EXCEL并提供下载 源码
- php使用 ZipArchive 压缩文件并提供下载
- ADO.net将数据导出到Excel并提供下载
- JoyiStar AJAX WebShop 3 Beta2正式发布并提供下载
- vs.net2008正式版发布并提供下载(英文版)
- 树形DP 三道例题(板子)
- Java中String直接赋字符串和new String的区别
- UVA
- C++后台面试常见问题与回答(持续更新)
- 2016CCPC杭州站 A
- 爬取携程网机票价格并提供搜索功能
- opencv——利用图像金字塔合成图片
- 拜占庭将军问题
- Latex-WinEdt使用中的问题记载
- 比较排序算法的时间复杂度的下限
- GPU共享内存小结---pycuda
- 三字棋 人机对弈
- Erlang 并发编程基础之一
- Java中,File类使用(四):RandomAccessFile类读写文件