资源简介 (共27张PPT)Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.少儿编程课火车票查询工具本节课我们来编写一个爬虫案例,制作12306火车票查询工具现在我们开始制作这个查询工具,首先获取接口1打开12306,在余票查询页面,点击F12,点击查询按钮在Network中可以看到本次查询时所有的网络请求接口12接口参数与网页填写数据对应关系:这里第二个接口就是火车票数据查询接口,如下:https://kyfw./otn/leftTicket/query leftTicketDTO.train_date=2017‐09‐25&leftTicketDTO.from_station=ZZF&leftTicketDTO.to_station=KFF&purpose_codes=ADULT其中:1、leftTicketDTO.train_date表示查询日期2、leftTicketDTO.from_station:表示出发地编码3、leftTicketDTO.to_station:表示目的地编码4、purpose_codes:表示票的类型,ADULT表示成人,如果是学生,则值为0X00访问这个接口地址,获取本次查询的全部JSON数据1返回的数据如下:分析数据接下来,我们对得到的数据进行分析,先规整数据把数据中的result部分(车票部分)存入文本,然后导入到excel(用|分割即可),删除没用的列,空列等,最终效果如下:1然后将数据和12306上的查询数据作对比12306查询数据如下:12将每列的含义分析出来Python获取数据分析完数据之后,剩下的工作就是获取数据然后展示了,首先获取数据定义获接口数据的方法,先拼接完整路径1访问接口地址2def get_json(url, train_date, from_station, to_station,purpose_codes='ADULT'):url = url + ' leftTicketDTO.train_date=' \+ train_date + '&leftTicketDTO.from_station=' \+ from_station + '&leftTicketDTO.to_station='\+ to_station + '&purpose_codes=' + purpose_codesreq = request.Request(url)分析完数据之后,剩下的工作就是获取数据然后展示了,首先获取数据向请求头添加User—Agent信息,模拟浏览器登陆12向请求头添加Cookie信息req.add_header('User‐Agent', 'Mozilla/5.0 (Windows NT 10.0; WOW64)''AppleWebKit/537.36 (KHTML, like Gecko)'' Chrome/56.0.2924.87Safari/537.36')req.add_header('Cookie', 'BLPROV=; JSESSIONID=17F82C085BEAE9774B1D7D18363207AA; ''route=6f50b51faa11b987e576cdb301e545c4; ''BIGipServerotn=1473839370.50210.0000; fp_ver=4.5.1; ''RAIL_EXPIRATION=1505522206734; RAIL_DEVICEID=ngfa0xXXc43AwRde''PQiYKNAXLxgF_0NC4u29FDPVr73XbEdk2jAZXdZmGwbMs5tmX28EVf3pqQWywtJRAN ''yU‐F1F4o1jEN2J8gI5mQVerkJAel9E5ACri_F7hggwk7zmV0IkRNjiH5CA0RFxBPLTsBkmBvAJ9_;'' current_captcha_type=C; _jc_save_fromStation=%u90D1%u5DDE%2CZZF;'' _jc_save_toStation=%u5F00%u5C01%2CKFF; _jc_save_fromDate=2017‐09‐25;'' _jc_save_toDate=2017‐09‐25; _jc_save_wfdc_flag=wf')3向请求头添加Cookie信息with request.urlopen(req) as f:return json.loads(f.read())然后将数据展示定义数据展方法,首先调用获取数据方法获取数据13根据数据分析的结果,将json拆分展示输出标题24运行程序,结果如下:def list_ticket():json_result = get_json('https://kyfw./otn/leftTicket/query', '2018‐11‐12','ZZF', 'KFF')list_tickets = json_result['data']['result']print("车次", "始发站", "终点站", "出发站", "到达站", "出发时间","到达时间", "历时", "商务座", "一等座", "二等座", "软卧","硬卧", "软座","硬座", "无座", "备注")for ticket in list_tickets:list_ticket_item = ticket.split('|')print(list_ticket_item[3], list_ticket_item[4],list_ticket_item[5], list_ticket_item[6],list_ticket_item[7], list_ticket_item[8],list_ticket_item[9], list_ticket_item[10],list_ticket_item[32], list_ticket_item[31],list_ticket_item[30], list_ticket_item[23],list_ticket_item[28], list_ticket_item[24],list_ticket_item[29], list_ticket_item[26],list_ticket_item[11])输出结果美化虽然查询出了结果,但是可以看到车站名称不是中文而是编码,而且格式比较乱在余票查询页面上右击 查看源代码 找到如下js文件:点击该js文件链接可以看到该文件包含了全部的站名称和对应编码,根据该文件,前端页面把从后台查询到的编码转为了火车站中文名称12所以,我们就可以根据这个文件中的站名和编码,自行转换输出结果中的编码新建py文件,使用python获取站名和对应编码导入相关库13编写正则获取编码和站名使用requests获取数据24获取到的stations如下:import reimport requestsfrom pprint import pprinturl = 'https://kyfw./otn/resources/js/framework/station_name.js station_version=1.9025'response = requests.get(url, verify=False)stations = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)通过正则获得的数据是一个有许多元祖组成的列表,每一个元祖包含中文站名和对应编码[(‘北京北’,‘VAP’),(‘北京东’,‘BOP’),(‘北京’,‘BJP’),(‘北京南’,‘VNP’),(‘北京西’,‘BXP’),(‘广州南’,‘IZQ’),(‘重庆北’,‘CUW’),(‘重庆’,‘CQW’), (‘重庆南’,‘CRW’),(‘重庆西’,‘CXW’),(‘广州东’,‘GGQ’), (‘上海’,‘SHH’),(‘上海南’,‘SNH’),(‘上海虹桥’,‘AOH’), (‘上海西’,‘SXH’)……]将这些元祖转为字典,就能够方便的转换编码和中文站名了,在这之前,我们先来了解两个python的内置函数dict和zipPython内置函数dict和zipdict(),用于创建、返回一个字典21zip(),参数为可迭代的对象,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。dict(a='a', b='b', t='t') # 传入关键字# 返回值 {'a': 'a', 'b': 'b', 't': 't'}dict(zip(['one', 'two', 'three'], [1, 2, 3])) # 映射函数方式来构造字典# 返回值 {'three': 3, 'two': 2, 'one': 1}dict([('one', 1), ('two', 2), ('three', 3)]) # 可迭代对象方式来构造字典# 返回值 {'three': 3, 'two': 2, 'one': 1}a = [1,2,3]b = [4,5,6]zipped = zip(a,b) # 打包为元组的列表# 返回值 [(1, 4), (2, 5), (3, 6)]接下来,我们就将数据转为字典将字典的键和值反转21将stations转为字典stations_dict = dict(stations)dict_res = dict(zip(stations_dict.values(), stations_dict.keys()))3将两个字典输出,结果如下:回到12306文件,将编码替换为中文从文件中导入两个字典13将结果中的站台编码转为中文,通过对反转后的字典进行取值实现from .stations_dict import stations_dictfrom .stations_dict_res import stations_dict_resprint( ……stations_dict_res.get(list_ticket_item[4]),stations_dict_res.get(list_ticket_item[5]),stations_dict_res.get(list_ticket_item[6]),stations_dict_res.get(list_ticket_item[7]),……json_result = get_json('https://kyfw./otn/leftTicket/query', train_date, stations_dict.get(from_station),stations_dict.get(to_station))增加中文查询功能,通过对未反转的字典进行取值实现2转换后,输出结果如下:第三方库prettytable使用第三方模块prettytable对控制台输出结果美化,首先来安装打开CMD,输入pip install prettytable1按下回车,将会自动下载安装2安装完成后,将其导入3from prettytable import PrettyTablept = PrettyTable()pt._set_field_names('车次 始发站 终点站 出发站 到达站 出发时间 到达时间 历时 商务座 一等座 二等座 软卧 硬卧 软座 硬座 无座 备注'.split())在结果展示方法中,创建实例,并设置标题3使用第三方模块prettytable对控制台输出结果美化,首先来安装使用add_row方法将之前直接输出的内容添加到实例中1最终效果如下:2pt.add_row([list_ticket_item[3], stations_dict_res.get(list_ticket_item[4]),stations_dict_res.get(list_ticket_item[5]),stations_dict_res.get(list_ticket_item[6]), stations_dict_res.get(list_ticket_item[7]),list_ticket_item[8], list_ticket_item[9], list_ticket_item[10], list_ticket_item[32],list_ticket_item[31],list_ticket_item[30], list_ticket_item[23], list_ticket_item[28], list_ticket_item[24],list_ticket_item[29], list_ticket_item[26], list_ticket_item[11]])print(pt)补充说明:如果在请求HTTPS协议时碰到证书问题,则在最前面加上一句:ssl._create_default_https_context = ssl._create_unverified_context1总结Summaryjson数据获取与解析√requests库的使用√第三方库prettytable的使用√Thanks! 展开更多...... 收起↑ 资源预览