在前两篇文章的基础上:
12306车站信息爬取(1)——输入条件的判断,包括出发站,到达站,和出发时间,并获取车次信息的链接
12306车站信息爬取(2)——输入出发站,到达站和出发时间,获取车次信息的列表
我们已经获取了车次的列表信息,在接下来的这篇文章中,主要涉及到的内容有:使用prettytable模块和colorama模块使输出结果美化。
(1)安装prettytable模块和colorama模块:
因为prettytable模块和colorama模块都不是系统内置的模块,都属于第三方模块,所以,我们需要先进行模块的安装。
(cmd——>pip install 模块名)由于我已经安装过了,所以,显示结果如下:
C:\Users\Lenovo>pip install colorama
Requirement already satisfied: colorama in c:\python36\lib\site-packages
C:\Users\Lenovo>pip install prettytable
Requirement already satisfied: prettytable in c:\python36\lib\site-packages
(2)示例:
我们先做一个简单的示例,作为参考,帮助大家更好的理解prettytable模块和colorama模块
使用prettytable的简单示例:
from prettytable import PrettyTable
def pretty_print():
infos=[[11,12,13,14,15,16,17],[21,22,23,24,25,26,27],[31,32,33,34,35,36,37]]
ptable=PrettyTable('list1 list2 list3 list4 list5 list6 list7'.split())
for info in infos:
ptable.add_row(info)
print(ptable)
pretty_print()
结果如下:
使用colorama的简单示例:
from prettytable import PrettyTable
from colorama import init, Fore
init(autoreset=False)
def pretty_print():
my_list1=[11,12,13,14,15,16,17]
my_list2 = [21,22,23,24,25,26,27]
my_list3=[31,32,33,34,35,36,37]
infos=[my_list1,my_list2,my_list3]
#改变列表中第一个元素的颜色
#并高亮显示,加上最后的Fore.RESET,会使得之后的元素不受影响,保持原样
my_list1[0]=Fore.LIGHTRED_EX + str(my_list1[0]) #没有加 Fore.RESET,之后的颜色都为红色
my_list2[0] = Fore.LIGHTGREEN_EX + str(my_list2[0]) + Fore.RESET
my_list3[0] = Fore.LIGHTYELLOW_EX + str(my_list3[0]) + Fore.RESET
ptable=PrettyTable('list1 list2 list3 list4 list5 list6 list7'.split())
for info in infos:
ptable.add_row(info)
print(ptable)
pretty_print()
结果如下:在改变颜色的最后加上Fore.RESET,可以使得之后的元素不受影响,保持原样,如果没有加 Fore.RESET,例如第一行的红色,之后的颜色都为红色。
通过上面两个代码,可以让大家简单的对这两个模块有所了解,再结合火车站的运用,可以有更深入的了解。
(3)车站信息爬取:
代码如下:
import json
import requests
import datetime
from colorama import init, Fore
from prettytable import PrettyTable
init(autoreset=False)
print("欢迎进入火车票查询系统".center(100, "="))
url='https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9090'
html_text=requests.get(url).text
#去掉文本总最后多余的两个符号,并以@符号进行分割,第一项不是有用的信息
infos=html_text[:-2].split("@")[1:]
stations={}
for info in infos:
station_list=info.split("|")
#将车站的代码作为键,汉字,全拼,简拼作为值
stations[station_list[2]]={'cn':station_list[1],'qp':station_list[3],'jp':station_list[4]}
#出发站,到达站的判断
def station_info(input_station):
while 1:
index = 0
results = []
station_results = []
for k,v in stations.items():
if input_station in v.values():
index += 1
station_results.append([k,v])
results.append([index, k, v['cn']])
if index == 0:
input_station = input("您输入的车站不存在,请重新输入站点:").strip()
#输入的信息唯一
elif index == 1:
#print(station_results[0])
station_code = station_results[0][0]
return station_code
break
#输入的信息模糊,不能直接判断出你想输入的站点,需要作出一个选择
else:
for result in results:
print(result[0], result[1], result[2])
select = int(input("请输入你的选择(序号):"))
for i in range(1, len(results)):
if select == i:
print(results[i-1])
station_code = station_results[i - 1][0]
return station_code
break
#出发日期的判断
def riqi_info(input_riqi):
# 用一个列表去存放可以查出车票的日期
riqi_list = []
today_riqi = datetime.date.today()
for i in range(15):
tianshu = datetime.timedelta(days=i)
riqi_list.append(str(today_riqi + tianshu))
#输入合理的日期则跳出,否则一直输入
while 1:
if input_riqi in riqi_list:
return input_riqi
break
else:
print("您输入的日期有误,请输入未来十五天内的日期进行查询!")
input_riqi = input("请输入出发的日期(2019-01-01):").strip()
chufa_station=input("请输入出发站:").strip()
chufa_code=station_info(chufa_station)
daoda_station=input("请输入到达站:").strip()
daoda_code=station_info(daoda_station)
input_riqi=input("请输入出发的日期(2019-01-01):").strip()
chufa_riqi=riqi_info(input_riqi)
train_url='https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(chufa_riqi,chufa_code,daoda_code)
#处理json格式的文件
web_data = requests.get(train_url)
#获取data
json_data = web_data.json()['data']
#获取result
json_result = json_data['result']
tickets = []
#针对每个链接,我们进行处理
for ticket in json_result:
#通过|对每个链接进行分割,分别获取我们所需信息对应的索引
ticket_list = ticket.split("|")
yuding = ticket_list[1]
#车次在索引为3的位置,以下类似
checi = ticket_list[3]
shifa_codes = ticket_list[4]
zhongdian_codes = ticket_list[5]
from_code = ticket_list[6]
to_code = ticket_list[7]
chufa_time = ticket_list[8]
daoda_time = ticket_list[9]
total_time = ticket_list[10]
vip = ticket_list[32]
yideng = ticket_list[31]
erdeng = ticket_list[30]
gaoji_ruanwo = ticket_list[21]
yideng_ruanwo = ticket_list[23]
erdeng_ruanwo = ticket_list[28]
dongwo = ticket_list[33]
yingzuo = ticket_list[29]
wuzuo = ticket_list[26]
qita = "--"
for s in stations:
if from_code in s:
from_station = stations[s]["cn"]
if to_code in s:
to_station = stations[s]["cn"]
#更改颜色,车次,出发站,到达站,出发时间,到达时间
from_station = Fore.LIGHTRED_EX + from_station + Fore.RESET
to_station = Fore.LIGHTGREEN_EX + to_station + Fore.RESET
checi = Fore.LIGHTYELLOW_EX + checi + Fore.RESET
chufa_time = Fore.LIGHTRED_EX + chufa_time + Fore.RESET
daoda_time = Fore.LIGHTGREEN_EX + daoda_time + Fore.RESET
#为了使出发站和到达站,出发时间和到达时间显示在一行,所以加换行
tickets.append([checi, from_station+'\n'+to_station+'\n' , chufa_time+'\n'+daoda_time+'\n', total_time, vip,yideng, erdeng, gaoji_ruanwo, yideng_ruanwo, erdeng_ruanwo, dongwo, yingzuo, wuzuo, qita, yuding])
#加个表头信息,并以空格进行分割
ptable = PrettyTable('车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 高级软卧 软卧一等座 硬卧二等座 动卧 硬座 无座 其他 预定'.split())
#如果没有车票信息,则打印出‘--’
for t_info in tickets:
for i in range(len(t_info)):
if t_info[i] == '':
t_info[i] = '--'
#将每个车次的信息加入到表中,即表的一行
ptable.add_row(t_info)
print(ptable)
结果如下:
下一篇:12306车站信息爬取(4)——添加车票的票价的信息