小学课后服务 Python少儿编程 进阶篇:6-火车票查询工具 课件 (27张PPT)

资源下载
  1. 二一教育资源

小学课后服务 Python少儿编程 进阶篇:6-火车票查询工具 课件 (27张PPT)

资源简介

(共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中可以看到本次查询时所有的网络请求接口
1
2
接口参数与网页填写数据对应关系:
这里第二个接口就是火车票数据查询接口,如下:
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查询数据如下:
1
2
将每列的含义分析出来
Python获取数据
分析完数据之后,剩下的工作就是获取数据然后展示了,首先获取数据
定义获接口数据的方法,先拼接完整路径
1
访问接口地址
2
def 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_codes
req = request.Request(url)
分析完数据之后,剩下的工作就是获取数据然后展示了,首先获取数据
向请求头添加User—Agent信息,模拟浏览器登陆
1
2
向请求头添加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())
然后将数据展示
定义数据展方法,首先调用获取数据方法获取数据
1
3
根据数据分析的结果,将json拆分展示
输出标题
2
4
运行程序,结果如下:
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文件链接可以看到
该文件包含了全部的站名称和对应编码,根据该文件,前端页面把从后台查询到的编码转为了火车站中文名称
1
2
所以,我们就可以根据这个文件中的站名和编码,自行转换输出结果中的编码
新建py文件,使用python获取站名和对应编码
导入相关库
1
3
编写正则获取编码和站名
使用requests获取数据
2
4
获取到的stations如下:
import re
import requests
from pprint import pprint
url = '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和zip
Python内置函数dict和zip
dict(),用于创建、返回一个字典
2
1
zip(),参数为可迭代的对象,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
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)]
接下来,我们就将数据转为字典
将字典的键和值反转
2
1
将stations转为字典
stations_dict = dict(stations)
dict_res = dict(zip(stations_dict.values(), stations_dict.keys()))
3
将两个字典输出,结果如下:
回到12306文件,将编码替换为中文
从文件中导入两个字典
1
3
将结果中的站台编码转为中文,通过对反转后的字典进行取值实现
from .stations_dict import stations_dict
from .stations_dict_res import stations_dict_res
print( ……
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 prettytable
1
按下回车,将会自动下载安装
2
安装完成后,将其导入
3
from prettytable import PrettyTable
pt = PrettyTable()
pt._set_field_names('车次 始发站 终点站 出发站 到达站 出发时间 到达时间 历时 商务座 一等座 二等座 软卧 硬卧 软座 硬座 无座 备注'.split())
在结果展示方法中,创建实例,并设置标题
3
使用第三方模块prettytable对控制台输出结果美化,首先来安装
使用add_row方法将之前直接输出的内容添加到实例中
1
最终效果如下:
2
pt.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_context
1
总结
Summary
json数据获取与解析

requests库的使用

第三方库prettytable的使用

Thanks!

展开更多......

收起↑

资源预览