在前三篇文章的基础上:

12306车站信息爬取(1)——输入条件的判断,包括出发站,到达站,和出发时间,并获取车次信息的链接

12306车站信息爬取(2)——输入出发站,到达站和出发时间,获取车次信息的列表

12306车站信息爬取(3)——使用prettytable模块和colorama模块使输出结果美化

我们已经可以将车站的余票信息获取出来,但是还有一点不足,那就是车票的票价信息没有获取出来,所以,在这篇文章中,主要涉及到的内容有:添加车票的票价信息,使输出结果完整。

(1)解析票价的信息:

我们可以看出,result列表中的信息可以帮我们获取票价之外的信息,但是车票的信息在result的基础上是不能获取出来的。所以,要获取票价的信息,我们需要通过另外的链接或请求。

通过观察车票的页面,我们可以看到票价信息被隐藏起来了,需要手动的去点击查看。

那么我们如何获取请求票价的链接呢?

(在车票信息的页面——>右键——>检查——>Network——>查询——>然后再点击车次下方的三角——>就可以看到如下的信息——>点开就可以看到票价信息)

这时候我们已经找到了票价的信息,请求票价的链接如下所示:

https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=4f0000D3080I&from_station_no=01&to_station_no=08&seat_types=O4O&train_date=2019-01-25

关注链接中的 train_no、from_station_no、to_station_no、seat_types、train_date这几个参数。在与对应的车次的信息进行对比。

我们可以很清楚的看到,票价的请求链接中的信息在result列表中的字符串中都有对应,所以,我们按照之前的方法,将 train_no、from_station_no、to_station_no、seat_types、train_date几个信息获取出来。进而获得请求票价的链接。

(2)解析不同类型的座位的“键”:

如下图所示:

A4:软卧一等卧;    O:二等座;     WZ:无座;

还有其他信息大家可以对照着去寻找,这里我给出大家我找到的信息:

A9或P:  商务座;

M:  一等座;

O:  二等座;

A6:  高级软卧;

A4:  软卧一等卧;

F:  动卧;

A3:  硬卧二等卧;

A2:  软座;

A1:  硬座;

WZ:  无座;

(3)火车票查询的代码:

import json
import requests
import datetime
from colorama import init, Fore
from prettytable import PrettyTableinit(autoreset=False)
#获取车站的版本信息,进而获取车站的全拼,简拼,代码等信息
def get_station_version(stations):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:]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(stations,input_station):while 1:index = 0results = []station_results = []for k, v in stations.items():if input_station in v.values():index += 1station_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_codebreak# 输入的信息模糊,不能直接判断出你想输入的站点,需要作出一个选择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_codebreak# 出发日期的判断
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_riqibreakelse:print("您输入的日期有误,请输入未来十五天内的日期进行查询!")input_riqi = input("请输入出发的日期(2019-01-01):").strip()#对链接进行解析,获取需要的信息的位置
def get_station_list(stations,chufa_riqi,chufa_code, daoda_code,tickets):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)# 获取datajson_data = web_data.json()['data']# 获取resultjson_result = json_data['result']# 针对每个链接,我们进行处理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 = "--"# 链接的部分train_no = ticket_list[2]from_station_no = ticket_list[16]to_station_no = ticket_list[17]seat_types = ticket_list[35]for s in stations:if from_code in s:from_station = stations[s]["cn"]if to_code in s:to_station = stations[s]["cn"]get_price_info(tickets,checi, from_station, to_station , chufa_time , daoda_time,total_time,vip,yideng, erdeng, gaoji_ruanwo, yideng_ruanwo, erdeng_ruanwo, dongwo, yingzuo, wuzuo, train_no, from_station_no, to_station_no, seat_types, chufa_riqi, qita, yuding)#得到价格信息
def get_price_info(tickets,checi, from_station, to_station , chufa_time , daoda_time,total_time,vip,yideng, erdeng, gaoji_ruanwo, yideng_ruanwo, erdeng_ruanwo, dongwo, yingzuo, wuzuo, train_no, from_station_no, to_station_no, seat_types, chufa_riqi, qita, yuding):link = 'https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no={}&from_station_no={}&to_station_no={}&seat_types={}&train_date={}'.format(train_no, from_station_no, to_station_no, seat_types, chufa_riqi)try:link_text = requests.get(link)link_json = link_text.json()['data']# 解析是什么座位,并加上颜色for j in link_json:if j == 'A9':vip = vip + "\n" + (Fore.LIGHTBLUE_EX + link_json['A9'] + Fore.RESET)if j == 'P':vip = vip + "\n" + (Fore.LIGHTBLUE_EX + link_json['P'] + Fore.RESET)if j == 'M':yideng = yideng + "\n" + (Fore.LIGHTBLUE_EX + link_json['M'] + Fore.RESET)if j == 'O':erdeng = erdeng + "\n" + (Fore.LIGHTBLUE_EX + link_json['O'] + Fore.RESET)if j == 'A6':gaoji_ruanwo = gaoji_ruanwo + "\n" + (Fore.LIGHTBLUE_EX + link_json['A6'] + Fore.RESET)if j == 'A4':yideng_ruanwo = yideng_ruanwo + "\n" + (Fore.LIGHTBLUE_EX + link_json['A4'] + Fore.RESET)if j == 'F':dongwo = dongwo + "\n" + (Fore.LIGHTBLUE_EX + link_json['F'] + Fore.RESET)if j == 'A3':erdeng_ruanwo = erdeng_ruanwo + "\n" + (Fore.LIGHTBLUE_EX + link_json['A3'] + Fore.RESET)if j == 'A1':yingzuo = yingzuo + "\n" + (Fore.LIGHTBLUE_EX + link_json['A1'] + Fore.RESET)if j == 'WZ':wuzuo = wuzuo + "\n" + (Fore.LIGHTBLUE_EX + link_json['WZ'] + Fore.RESET)color_list = get_color_info(checi, from_station, to_station, chufa_time, daoda_time)# 为了使出发站和到达站,出发时间和到达时间显示在一行,所以加换行tickets.append([color_list[2], color_list[0] + '\n' + color_list[1] + '\n', color_list[3] + '\n' + color_list[4] + '\n',total_time, vip, yideng, erdeng, gaoji_ruanwo, yideng_ruanwo, erdeng_ruanwo, dongwo, yingzuo, wuzuo, qita,yuding])except:pass# 为了使出发站和到达站,出发时间和到达时间显示在一行,所以加换行tickets.append([color_list[2], color_list[0] + '\n' + color_list[1] + '\n', color_list[3] + '\n' + color_list[4] + '\n', total_time, vip, yideng, erdeng, gaoji_ruanwo, yideng_ruanwo, erdeng_ruanwo, dongwo, yingzuo, wuzuo, qita, yuding])#将车次,出发站,到达站,出发时间,到达时间的颜色做改变
def get_color_info(checi, from_station, to_station , chufa_time , daoda_time ):# 更改颜色,车次,出发站,到达站,出发时间,到达时间from_station = Fore.LIGHTRED_EX + from_station + Fore.RESETto_station = Fore.LIGHTGREEN_EX + to_station + Fore.RESETcheci = Fore.LIGHTYELLOW_EX + checi + Fore.RESETchufa_time = Fore.LIGHTRED_EX + chufa_time + Fore.RESETdaoda_time = Fore.LIGHTGREEN_EX + daoda_time + Fore.RESETcolor_list=[from_station, to_station,checi,chufa_time , daoda_time]return color_list#使用prettytable模块表格化的输出信息
def print_station_infos(tickets):# 加个表头信息,并以空格进行分割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)#主函数,程序的入口
def main():stations = {}tickets=[]get_station_version(stations)     ##获取车站的版本信息,进而获取车站的全拼,简拼,代码等信息chufa_station = input("请输入出发站:").strip()chufa_code = station_info(stations,chufa_station)daoda_station = input("请输入到达站:").strip()daoda_code = station_info(stations,daoda_station)input_riqi = input("请输入出发的日期(2019-01-01):").strip()chufa_riqi = riqi_info(input_riqi)get_station_list(stations,chufa_riqi,chufa_code, daoda_code,tickets)  ##对链接进行解析,获取需要的信息的位置print_station_infos(tickets)  #使用prettytable模块表格化的输出信息main()

结果如下:

票价信息就被我们成功的获取出来了,如果大家有什么建议,欢迎留言,一起讨论。

12306车站信息爬取(4)——添加车票的票价信息相关推荐

  1. 12306车站信息爬取(1)——输入条件的判断,包括出发站,到达站,和出发时间,并获取车次信息的链接

    12306车站信息的爬取是一个比较复杂的系统,爬取需要的信息不是很难,但是要将最终的结果做的完善和美观却不是那么容易.作为一个学习Python的新手,我想把练习和整理结合起来,希望大家可以相互交流和探 ...

  2. 北京房租到底有多高? | 爬取北京海淀区一居室租房信息

    图片来源:花瓣网 文章来源 人工智能与大数据生活 如需转载,请联系原作者授权 最近北京房租成了热门话题,到底北京的房租有多高? 本次实战是爬取北京海淀区一居室的租房信息,共爬取了300套房源信息,看一 ...

  3. python爬房源信息_用python爬取链家网的二手房信息

    题外话:这几天用python做题,算是有头有尾地完成了.这两天会抽空把我的思路和方法,还有代码贴出来,供python的初学者参考.我python的实战经历不多,所以代码也是简单易懂的那种.当然过程中还 ...

  4. 网易云音乐用户信息爬取以及可视化

    选的课程方向是爬取网易云音乐某首歌曲的用户评论内容和评论时间,观察每天哪个时间段的评论信息最多,每周哪天的评论信息最多.然后分析该歌曲的用户性别分布和年龄分布.所以首先需要通过爬虫来爬取评论信息和用户 ...

  5. Python爬取豆瓣电影top250的电影信息

    Python爬取豆瓣电影top250的电影信息 前言 一.简介 二.实例源码展示 小结 前言 相信很多小伙伴在学习网络爬虫时,老师们会举一些实例案例讲解爬虫知识,本文介绍的就是经典爬虫实际案例–爬取豆 ...

  6. 【爬虫】应用Python爬虫爬取豆瓣租房上的帖子信息

    GitHub项目地址:https://github.com/Donvink/Spider.BC 哔哩哔哩代码讲解:https://b23.tv/waSfUa CSDN博客地址:https://blog ...

  7. 【2020-10-27】 scrapy爬虫之猎聘招聘信息爬取

    声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢! scrapy爬虫之猎聘招聘信息爬取 1.项目场景 目标网址:https://www.liepin.com/zhao ...

  8. Scrapy框架爬虫项目:京东商城笔记本电脑信息爬取

    一.创建Scrapy项目 在cmd中输入一下指令创建一个新的scrapy项目及一个爬虫 scrapy startproject JD_Goodscd JD_Goodsscrapy genspider ...

  9. 爬取正方教务管理系统获取学生信息

    新版正方教务系统请点这里:模拟登陆新版正方教务管理系统(获取学籍信息.课表和成绩) 最近想学点爬虫玩玩,拿学校的教务系统练练手.学校与很多高校一样,用的是正方教务管理系统,非常的不好用,经常出现登陆不 ...

最新文章

  1. 性能测试学习过程中遇到的问题与解答1
  2. IT团队如何安全地加速云计算的采用
  3. mysql charindex_mysql中替代charindex的函数substring_index、find_in_set | 学步园
  4. string 字符串中字符无效_7.3 C++字符串类 | 使用string输出
  5. 【双100%解法】剑指 Offer 22. 链表中倒数第k个节点
  6. 在Eclipse中运行hadoop程序
  7. php foreach id是否存在数组_请纠正这 5 个 PHP 编码小陋习
  8. python学习如何从菜鸟到老手
  9. Java队列Disruptor 的使用
  10. HCL打开显示当前系统用户怎么解决_鼠标右键新建没有EXCEL 怎么解决?
  11. 整理 Mac 安装 oracle
  12. Java Graphics2D 在图片上画(微信昵称)含有特殊符号(Emoji)的文字
  13. BM3D算法半解,带python代码
  14. SECS/GEM协议库开发开源代码
  15. c语言的if语句案例,c语言if语句(c语言if语句例子)
  16. PLG日志平台搭建: Promtail + Loki + Grafana 全步骤
  17. cesium添加高德影像图
  18. 为什么需要 Mini-batch 梯度下降,及 TensorFlow 应用举例
  19. 使用python异步框架aiohttp从NASA抓取火星图片
  20. 设计模式学习(九):Builder

热门文章

  1. 谁的用户在世界上是#160;#160;明基决心保时捷设计标准
  2. 华为鸿蒙微波炉,再见EMUI,你好鸿蒙!华为不止做手机
  3. 第939期机器学习日报(2017-04-14)
  4. java蛮力法背包问题_蛮力法、动态规划法 求解01背包问题
  5. 拉网小调(民歌介绍)
  6. springboot将文件响应给前端
  7. ThreeJS - 直接设置Fbx模型的某个关节的位移和旋转值
  8. 万国觉醒服务器维护,《万国觉醒》怎么换服 更换服务器方法攻略
  9. 【Stochastic Depth】《Deep Networks with Stochastic Depth》
  10. 勒让德n项多项式的m次求导