12306火车票余票查询器


文章同步更新:http://www.riba2534.cn/?p=305
今天写了一个12306火车票余票查询器的爬虫,在这里记录一下过程.

首先先看一下最终效果:

比如想查9月2日从西安—北京动车特快的余票

tickets.py -dg 西安 北京 2017-09-02

效果预览:

首先我们梳理一下用到的工具:

  1. Python3.x(必备)
  2. requests库,用来进行http请求的访问
  3. docopt库,用来实现命令行参数处理(使用方法)
  4. prettytable,使信息以好看的表格形式呈现出来
  5. colorama,用来设置命令行中显示的颜色

一、前期准备

我们的主程序就叫做tickets.py,因为我们是用的带参数的形式实现程序,所以我们要先进行参数的声明:
我们先:from docopt import docopt

"""命令行火车余票查询器
Usage:tickets [-gdtkz] <from> <to> <date>Options:-h,--help   显示帮助菜单-g          高铁-d          动车-t          特快-k          快速-z          直达
"""

这些信息会存储在__doc__中,docopt会对这个信息进行解析然后返回我们需要的信息,解析的代码如下:

二、解析URL

既然要写爬虫,那么首先肯定是要对URL进行解析了,我们要爬取的是12306的网站,那么我们首先找到查询余票的网站:

https://kyfw.12306.cn/otn/leftTicket/init

我们会看到这个:

然后进行抓包,我们会发现一个GET请求:

也就是这个链接:
https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-09-01&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=BJP&purpose_codes=ADULT
我们通过观察就会发现这个请求里面有4个参数:

  • leftTicketDTO.train_date=2017-09-01
  • leftTicketDTO.from_station=XAY
  • leftTicketDTO.to_station=BJP
  • purpose_codes=ADULT

我们通过观察就可以知道,这四个属性分别对应着:查询的时间,出发的站点,结束的站点,票的种类

现在发现了一个问题,出发站点和结束站点的值为什么都是英文,这些字母肯定表示的是城市的名称,那么我们现在就要去寻找这些城市的代码,我们查看网页源代码

发现了一个JS文件,打开以后会发现

这个页面竟然包含着全部的站点名称和对应的代码,所以我们只需要把这些东西解析一下,就可以得到车站和对应的代码了.

所以我们就有了思路了,我们应该先用requests来获取这个页面,然后再用正则表达式来把对应的信息解析一下,然后进行一些处理就好了,关于正则表达式的使用,不会的童鞋还是去百度百度吧~
根据网页上面的信息,我们可以写出如下正则表达式:

([\u4e00-\u9fa5]+)|([A-Z]+)

先匹配汉字,然后后面匹配字母,中间有一个分隔符,完整的代码.

我们建一个文件parser_stations.py解析:

使用方法是运行这个文件,然后把这个文件的结果重定向到一个新文件:

python parser_stations.py > stations.py

然后对新的文件进行处理:

这样我们就可以通过stations.py里面的两个函数进行获取操作了,这样的话我们就可以构造出我们需要的URL

url=('https://kyfw.12306.cn/otn/leftTicket/query?''leftTicketDTO.train_date={}&''leftTicketDTO.from_station={}&''leftTicketDTO.to_station={}&''purpose_codes=ADULT').format(date,from_station,to_station)

三、解析火车票的信息

我们现在已经获取到了url,我们现在就可以对其访问,还是用requests来访问我们构造好的URL,比如我们构造的是2017-09-02从西安到北京的火车,那么url是:https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2017-09-02&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=BJP&purpose_codes=ADULT
我们进入后会看到:

很明显,这是一个json信息,我们用requests自带的json解析器来进行解析,会得到一个列表:

r=requests.get(url,verify=False,headers=headers)
r.encoding=r.apparent_encoding
raw_trains=r.json()['data']['result']

这个列表里面:

  • 6,7元素代表起点和终点的名称
  • 8,9元素代表这趟列车出发和到达的时间
  • 10号元素代表,列车的用时
  • 31代表一等座,30代表二等座
  • 23,28,29代表软卧,硬卧,硬座
  • 26代表无座的信息

我们知道了每个元素代表的信息,只需要把它们呈现出来就可以了,我们先创建一个prettytable对象:

pt=PrettyTable() #初始化一个prettytable对象
pt._set_field_names('车次 车站 时间 历时 一等座 二等座 软卧 硬卧 硬座 无座'.split())

然后弄好表格的标题后,插入列:

for raw_train in raw_trains:                   #对每一趟列车进行解析data_list=raw_train.split('|')train_no=data_list[3]initial=train_no[0].lower()  #获取首字母,表示车次if not options or initial in options:   #如果没有设置options或者首字母在options里面from_station_code=data_list[6]to_station_code=data_list[7]start_time=data_list[8]arrive_time=data_list[9]time_duration=data_list[10]first_class_seat=data_list[31] if data_list[31] else '--'second_class_seat=data_list[30] if data_list[30] else '--'soft_sleep=data_list[23] if data_list[23] else '--'hard_sleep=data_list[28] if data_list[28] else '--'hard_seat=data_list[29] if data_list[29] else '--'no_seat=data_list[26] if data_list[26] else '--'pt.add_row([Fore.YELLOW + train_no + Fore.RESET,'\n'.join([Fore.GREEN + stations.get_name(from_station_code) + Fore.RESET,Fore.RED + stations.get_name(to_station_code) + Fore.RESET]),'\n'.join([Fore.GREEN + start_time + Fore.RESET,Fore.RED + arrive_time + Fore.RESET]),time_duration,first_class_seat,second_class_seat,soft_sleep,hard_sleep,hard_seat,no_seat])
print(pt)

在这里面用了colorama来对命令行里面的字符进行上色,相关用法去百度找找就行了~


代码长得比较丑陋,还请不要嫌弃,主要作为练手之用,所以懒得重构代码了,相关的源代码已经上传至Github,欢迎提出问题和Bug…

GitHub地址:https://github.com/riba2534/12306Tickets_search

(^▽^)

Python爬虫----12306火车票余票查询器相关推荐

  1. python爬虫实现火车票余票查询

    python爬虫实现火车票余票查询 获取终端输入的命令行参数 重构请求url,解析返回的json数据 获取终端输入的命令行参数 例如:python3 tickets.py -dg 成都 南京 2016 ...

  2. 项目实战一 12306火车票余票查询软件

    1.安装docopt.urllib.requests 2.实现程序基础框架 # -*- coding:utf-8 -*-""" Train tickets query p ...

  3. 12306火车余票查询

    测试地址:http://gengjian.24.lc/japson/123060.htm 调用12306官网的查询接口. 123060.htm 火车票余票查询Demo By Genng.<br& ...

  4. 12306实时余票查询接口

    12306实时余票查询接口代码文档及返回示例,可查询实时火车票余票,包括车次.车次始发站.车次终点站.出发时间.到达时间.车次类型.总历时时间等等. 接口名称:12306实时余票查询接口 接口平台:聚 ...

  5. 12306之余票查询流程解析

    前言 本套教程共分3章: 12306之登录流程解析 12306之余票查询解析 12306之下单流程解析 本套内容主要用于分析12306购票流程,意在编写一套自动购票小程序.12306接口 api 经常 ...

  6. 实验楼 python 火车票余票查询

    Python 实现火车票查询工具 核心的几个地方: 1:正则表达式的构建 2:json数据的解析 一.实验简介 当你想查询一下火车票信息的时候,你还在上 12306 官网吗?或是打开你手机里的 APP ...

  7. 12306火车余票查询API

    简介 年关将近,看到此图未免一声长叹,惆怅不已.API中国将深挖可怕的12306网站,公布尽可能多的接口,希望某当世才俊能开发出一款能造福我朝的购票助手软件,定受无量加持-- 扯远了,扯回来. 使用1 ...

  8. Oracle:简单分析火车票余票查询和座位剩余

    引用CSDN论坛上的一个问题,http://bbs.csdn.net/topics/392284590 ,开始思路错误,给了一个错误的答案,然后仔细分析了一下 题目如下: 假设有一个车次1经过5个站, ...

  9. 火车余票查询(python)

    通过python可以对火车票余票进行查询. 一.获取并构建url地址 进入12306火车票查询,点击F12,尝试查询北京到上海的火车票,可以看到,它从某个url地址获取到了相关json类型数据,而返回 ...

最新文章

  1. linux查看文件安全权限,Linux系统下如何查看及修改文件读写权限
  2. Spring Cloud第六章:配置中心Config
  3. Apache 配置关闭文件目录浏览
  4. IDEA打开html文件时显示错误browser error提示找不到chrome或者别的浏览器
  5. 关键字驱动小例子_example2
  6. leetcode - First Missing Positive
  7. NB-IoT四大关键特性及实现告诉你,为啥NB
  8. 2015/8/29 Python基础(3):数值
  9. element下拉框回显问题
  10. 区块链技术对大数据有哪些影响
  11. 创业者应该思考智能硬件能为灾难做什么
  12. 能够编辑excel的python 软件有哪些_生产管理系统有哪些
  13. ae效果英文版翻译对照表_AE菜单中英文对照表 (超全)
  14. springboot网上订餐管理系统设计与实现.rar(项目源码)
  15. CSS内联样式表、内部样式表、外部样式表
  16. 【Bug】Microsoft Edge拒绝访问
  17. idea常见问题-个人而言
  18. 超详细图文保姆级教程:App开发新手入门(六)
  19. Excel数据分析:从入门到精通
  20. Docker+Frp+NGinx+云服务器 实现HTTPS内网穿透

热门文章

  1. 【JAVA】二分查找
  2. 苹果x浏览器显示服务器停止,苹果浏览器服务器停止打不开网页
  3. 文件上传漏洞 解析、验证、伪造(一)
  4. 机器人最新天赋符文天赋加点图_LOLS6新版机器人怎么点天赋 新版机器人天赋符文攻略...
  5. RabbitMQ消息丢失以及解决策略
  6. 工业微型计算机视频,工业微型计算机辅导
  7. AJAX实现百度搜索栏效果
  8. cia转cci,手把手教你轻松搞定!
  9. linux系统安装pycharm的桌面图标快捷方式图标是空白的解决方案
  10. 马斯克在推特回应推特起诉:真讽刺,我笑了