使用 Python 在 12306 查询火车票余票

本贴最后更新于 2352 天前,其中的信息可能已经事过景迁

实现原理比较简单,就是调用 12306 的查票接口获取 json 数据再重新组装,取出合适的数据。配合发送邮件模块,就能实现实时获取余票数据。

由于发现 12306 经常进行查票接口部分参数的更换,下面就以谷歌浏览器为例寻找一个查票接口:

如图,在谷歌浏览器的调试窗口 network 标签页下点击网页上的查询按钮可以看到一个 get 请求,其请求的数据就是我们需要的 json 数据。

QQ20181015235126png

看一下原生数据,在浏览器中打开这个链接:

imagepng

包含了我们需要的数据
再看一下这个链接:https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-10-17&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=KMM&purpose_codes=ADULT (会存在变动,非实时可用)

可以看出需要我们传递三个参数:

查询日期,如:2018-10-17
出发地火车站电报码,如:BJP (北京)
到达地火车站电报码,如:KMM (昆明)

不知道电报码的话百度一下就 ok 了。

好,现在就处理数据,看代码:
我们需要循环遍历每辆车的信息,原始数据 result 中每一条就是一个车次信息,其间采用竖线分隔。
使用 python 取子串获取的信息如下:

item = {} # 循环遍历每辆列车的信息 data_list = raw_train.split('|') train_type = data_list[3][0] print data_list # 车次号码 item['train_no'] = data_list[3] # 出发站 from_station_code = data_list[6] item['from_station_name'] = stations_list[from_station_code] # 终点站 to_station_code = data_list[7] item['to_station_name'] = stations_list[to_station_code] # 出发时间 item['start_time'] = data_list[8] # 到达时间 item['arrive_time'] = data_list[9] # 总耗时 item['time_fucked_up'] = data_list[10] # 商务特等 item['business_class_seat'] = data_list[25] or '--' # 一等座 item['first_class_seat'] = data_list[31] or '--' # 二等座 item['second_class_seat'] = data_list[30] or '--' print item['second_class_seat'] # 软卧 item['soft_sleep'] = data_list[23] or '--' # 硬卧 item['hard_sleep'] = data_list[28] or '--' # 硬座 item['hard_seat'] = data_list[29] or '--' # 无座 item['no_seat'] = data_list[26] or '--'

代码就自己看吧,很简单的 python 基础。

经过简单的组装,就得到了简单的示例程序,下面是完整代码:

# coding=utf-8 from time import sleep import datetime import requests import smtplib from email.mime.text import MIMEText import sys reload(sys) sys.setdefaultencoding('utf-8') def query_trains(data): url = 'https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format( data.date, data.form, data.to ) jsondata = "" #print requests.get(url).text while jsondata=="" or jsondata==None: try: print(url) print("try get json") jsondata = requests.get(url).json() # print jsondata except: jsondata = "" print("get json error") sleep(7) return jsondata def sort_trains(raw,data): flag=0 for_sale = [] not_for_sale = [] raw_trains = raw['data']['result'] stations_list = raw['data']['map'] content = "有新的车票啦!!\r\n车票信息如下:\r\n-------------------------\r\n" content+="运行区间:"+stations_list[data.form]+"---"+stations_list[data.to]+"---"+data.date+"\r\n" for i in raw_trains: train_data=i.split("|") if int(str(train_data[8])[0:2])<18 and int(str(train_data[8])[0:2])>0: #查找下午18点以前的火车 if train_data[0]=="": print str(train_data[3]+"--"+train_data[8]+"-"+train_data[10]+"-已售空") else: if train_data[26] != "" and train_data[26]!="无": # 无座 # print(str(train_data[3] + "--" + train_data[8] + "-" + train_data[10] + "-"+train_data[26])+ "-无座有票") content+=(str(train_data[3] + "--" + train_data[8] + "-" + train_data[10] + "-"+train_data[26])+ "-无座有票"+"\r\n") flag = 1 if train_data[29] != "" and train_data[29]!="无": # 硬座 # print(str(train_data[3] + "--" + train_data[8] + "-" + train_data[10] + "-"+train_data[29])+ "-硬座有票") content +=(str(train_data[3] + "--" + train_data[8] + "-" + train_data[10] + "-"+train_data[29])+ "-硬座有票"+"\r\n") flag = 1 if train_data[30]!="" and train_data[30]!="无": #二等座 # print(str(train_data[3]+"--"+train_data[8]+"-"+train_data[10]+ "-"+train_data[30]) + "-二等座有票") content +=(str(train_data[3]+"--"+train_data[8]+"-"+train_data[10]+ "-"+train_data[30]) + "-二等座有票"+"\r\n") flag = 1 content+="-------------------------\n" content += "时间:"+datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')+"\r\n" content += "Powered By:xynling" if flag==1: print content class TrainData: def __init__(self,form,to,date): self.form = form self.to=to self.date=date def main(): while True: if (int(datetime.datetime.now().strftime('%H'))>=6): td=TrainData('BJP','KMM','2018-10-17') sort_trains(query_trains(td),td) sleep(30) #休眠30s继续执行 else: print(int(datetime.datetime.now().strftime('%H'))) sleep(5) if __name__ == '__main__': main()

是循环 30 秒进行查询的。

查询结果如图:

imagepng

结合邮箱进行微信提醒:

imagepng

如果放在服务器上运行就能很方便的收到车票提醒啦!

实现原理部分摘自网络,文章原创,转载请注明转载自 ynlflixin 的个人博客!

😄

  • Python

    Python 是一种面向对象、直译式电脑编程语言,具有近二十年的发展历史,成熟且稳定。它包含了一组完善而且容易理解的标准库,能够轻松完成很多常见的任务。它的语法简捷和清晰,尽量使用无异义的英语单词,与其它大多数程序设计语言使用大括号不一样,它使用缩进来定义语句块。

    556 引用 • 674 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 2 关注
  • 服务

    提供一个服务绝不仅仅是简单的把硬件和软件累加在一起,它包括了服务的可靠性、服务的标准化、以及对服务的监控、维护、技术支持等。

    41 引用 • 24 回帖 • 1 关注
  • 酷鸟浏览器

    安全 · 稳定 · 快速
    为跨境从业人员提供专业的跨境浏览器

    3 引用 • 59 回帖 • 46 关注
  • Word
    13 引用 • 40 回帖
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    20 引用 • 7 回帖
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    76 引用 • 389 回帖
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 542 关注
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    70 引用 • 193 回帖 • 412 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 567 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    5 引用 • 7 回帖 • 2 关注
  • SpaceVim

    SpaceVim 是一个社区驱动的模块化 vim/neovim 配置集合,以模块的方式组织管理插件以
    及相关配置,为不同的语言开发量身定制了相关的开发模块,该模块提供代码自动补全,
    语法检查、格式化、调试、REPL 等特性。用户仅需载入相关语言的模块即可得到一个开箱
    即用的 Vim-IDE。

    3 引用 • 31 回帖 • 117 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 639 关注
  • Rust

    Rust 是一门赋予每个人构建可靠且高效软件能力的语言。Rust 由 Mozilla 开发,最早发布于 2014 年 9 月。

    58 引用 • 22 回帖 • 1 关注
  • CodeMirror
    1 引用 • 2 回帖 • 154 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    87 引用 • 139 回帖 • 1 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 1 关注
  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    116 引用 • 54 回帖 • 5 关注
  • WiFiDog

    WiFiDog 是一套开源的无线热点认证管理工具,主要功能包括:位置相关的内容递送;用户认证和授权;集中式网络监控。

    1 引用 • 7 回帖 • 606 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 75 关注
  • CentOS

    CentOS(Community Enterprise Operating System)是 Linux 发行版之一,它是来自于 Red Hat Enterprise Linux 依照开放源代码规定释出的源代码所编译而成。由于出自同样的源代码,因此有些要求高度稳定的服务器以 CentOS 替代商业版的 Red Hat Enterprise Linux 使用。两者的不同在于 CentOS 并不包含封闭源代码软件。

    239 引用 • 224 回帖 • 1 关注
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 319 关注
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    12 引用 • 54 回帖 • 168 关注
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    28 引用 • 226 回帖 • 138 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    171 引用 • 3842 回帖
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 676 关注