今天,你抢到票了吗?

今天网上开始预售除夕前一天的火车票。

这几天,办公室的小伙伴们每天准点蹲在电脑前,不停地刷新页面,可最终还是眼睁睁看着一秒之后就显示“无票”了。(╯‵□′)╯︵┻━┻

无奈之下,只能寄希望于之后几天会有些余票或者退票被放出来。但总不能接下来一直开着网页不停刷吧……好在我们还有 Python 啊,就让程序定时去查咯。

之前也放过查票的代码,参见:刷票有风险,抢购需谨慎

1. 我们用 Chrome 进入 12306 余票查询网页,打开开发者工具(右键“审查元素”或者 F12/ctrl+shift+i),菜单栏选择 Network。

2. 填写出发地和目的地以及出发日后(这里以1月11日上海到北京为例),点击“查询”,在 Network 栏目下,可以看到发出的所有请求。仔细观察后发现,其中一个带有 query 字样的地址就是余票的查询接口,从信息栏中 Headers 分页下的 Request URL 可以看到它的完整地址。

这里注意,12306 现在有两个查询余票的页面,不同页面上看到的接口地址是不一样的。分别是:

旧版:

https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2017-01-11&from_station=BJP&to_station=BJP

新版:

https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2017-01-11&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=BJP&purpose_codes=ADULT

两个接口的参数和返回值也不相同。这里我们用新版的接口。

在 Python 2 中,我们可以通过 urllib2 直接访问接口,获取返回数据。Python 3 可以使用 urllib.request 或者 requests 库。

req_url = 'https://kyfw.12306.cn/otn/leftTicket/queryZ?leftTicketDTO.train_date=2017-01-11&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=BJP&purpose_codes=ADULT'

resp = urllib2.urlopen(req_url)

resp_info = resp.read()

print resp_info

在程序中输出结果,或者直接在浏览器中打开这个请求地址,可以看到返回值。

如果请求时报错:

<urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:590)>

需要加上以下代码,忽略 ssl 证书的验证:

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

这些密密麻麻看上去有点像是字典格式的数据就是 json 数据。通过浏览器 json 插件或者搜索下 json 在线解析工具,可以让这些数据显示得更人性化。

不难看出,我们需要的车次余票信息就在每一车次全部相关信息中,而这也信息以字典列表的形式,储存在“data”的值中。因此,我们若要查询余票,就该先把 json 格式的数据转为字典,获取其中的 data 列表,然后遍历列表,查询车次,最后从该车次对应的字典字段中,查询余票。

info_json = json.loads(resp_info)
info = info_json['data']
for train_data in info:
    train = train_data['queryLeftNewDTO']
    if train['station_train_code'] == TRAIN:
        print '商务座:', train['swz_num']
        print '特等座', train['tz_num']
        ...
        print '无座', train['wz_num']
        print '其它', train['qt_num']

为了让程序一直查询下去,我们用一个条件为 True 的 while 循环。再配合上 time 模块的 sleep 方法(参数单位为秒),让程序每查询一次就休息一会儿。毕竟我们只是想要定时刷一下页面,没必要一直发送请求。

while True:
    # 查询余票代码
    time.sleep(600)

现在,在你的电脑上运行代码,就可以每隔 10 分钟自动去访问一次页面,看看是否有新的余票放出。当然,你得根据自己的需要,去修改请求地址里的日期和出发、到达站的代号。

在本公众号(crossincode)里回复 查票,获取本篇的完整示例代码。

如果你还希望程序在刷出票后,能给你发个邮件提醒的话,请查看我们之前的文章:简单三步,用 Python 发邮件 或者在公众号里回复 邮件

说明几点:

  1. 这个程序只是定时访问公开页面,查询余票信息,无需登录和验证码,但并不能自动替你购票。
  2. 请设定适当的查询间隔,没必要高频刷新。合理使用此脚本不会比手动刷新页面给网站带来更大压力,只是免去了你时刻关注页面的烦躁。
  3. 掌握这个方法,也可以查询其他购票网站,或用在类似的页面信息查询上。
  4. 由于最近在春运购票高峰,接口访问可能会比较慢,甚至请求失败。
  5. 这不是抢票工具,它做不到,我们也不建议使用类似工具干扰正常的购票秩序。

最后,祝大家身体健康,都能买上票,高高兴兴回家过年!

原文发布于微信公众号 - Crossin的编程教室(crossincode)

原文发表时间:2016-12-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

工业控制系统安全之——Modbus学习笔记

O、术语 1 word =2 byte; 1 byte =8 bit. 校验码:校验码是由前面的数据通过某种算法得出的,用以检验该组数据的正确性。代码作为数据在...

1K100
来自专栏程序员的SOD蜜

“设计应对变化”--实例讲解一个数据同步系统

 系列文章索引: [WCF邮件通信系统应用 之 数据同步程序 之 设计内幕 之 一] 同步一个数据库要发多少个数据包? [WCF邮件通信系统应用 之 数据同步...

28270
来自专栏Java架构

阿里面试题(一)

20360
来自专栏数据和云

当Java虚拟机遇上Linux Arena内存池

作者简介 刘韬,云和恩墨中间件服务交付团队专家 Java开发出身,10年WebLogic相关开发、运维工作经验,熟悉SOA、现代业务系统架构中各层组件,尤其擅长...

87370
来自专栏CDA数据分析师

Python大法好,跟着本宝宝用Python抢火车票!

前言:大家跟我一起念: Python大法好,跟着本宝宝用Python抢火车票! 具体步骤: 准备工作 首先我们需要splinter 安装: pip instal...

39890
来自专栏菩提树下的杨过

thrift中的超时(timeout)坑

最近在项目中采用thrift作为后台服务rpc框架,总体用下来性能还不错,跨语言特性使用起来也还行,但是也遇到了一些坑,其中之一就是超时问题(timeout),...

78290
来自专栏程序员的SOD蜜

单数据库,多数据库,单实例,多实例不同情况下的数据访问效率测试

最近公司的项目准备优化一下系统的性能,希望在数据库方面看有没有提升的空间,目前压力测试发现数据库服务器压力还不够大,Web服务器压力也不是很大的情况下,前台页面...

275100
来自专栏喔家ArchiSelf

MCU上的代码执行时间

在许多实时应用程序中,二八原则并不生效,CPU 可以花费95%(或更多)的时间在不到5% 的代码上。电动机控制、引擎控制、无线通信以及其他许多对时间敏感的应用程...

11620
来自专栏CDA数据分析师

手把手教你用python抢火车票

? 前言:大家跟我一起念,Python***好,跟着本宝宝用Python抢火车票 首先我们需要splinter 安装: pip install splinte...

53970
来自专栏魏艾斯博客www.vpsss.net

建站新手错把“一女嫁二夫” NS解析错误导致网站或企业邮箱打不开

NS解析对于经常建站的老手来说已经驾轻就熟了,添加 A 记录、MX 记录、CNAME 记录都很熟练,几分钟就可以搞定。不过对于建站新手来说还是比较蒙圈,搞不清什...

26930

扫码关注云+社区

领取腾讯云代金券