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

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

实现原理比较简单,就是调用 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 引用 • 675 回帖 • 1 关注

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    588 引用 • 3538 回帖
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1243 回帖 • 411 关注
  • 酷鸟浏览器

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

    3 引用 • 59 回帖 • 46 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖
  • JetBrains

    JetBrains 是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是 Java 编程语言开发撰写时所用的集成开发环境:IntelliJ IDEA

    18 引用 • 54 回帖 • 2 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    163 引用 • 310 回帖
  • 外包

    有空闲时间是接外包好呢还是学习好呢?

    26 引用 • 233 回帖 • 3 关注
  • OneNote
    1 引用 • 3 回帖
  • 叶归
    5 引用 • 16 回帖 • 11 关注
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    6 引用 • 15 回帖 • 24 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • SSL

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

    70 引用 • 193 回帖 • 408 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    52 引用 • 190 回帖
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 285 关注
  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 8 关注
  • 小说

    小说是以刻画人物形象为中心,通过完整的故事情节和环境描写来反映社会生活的文学体裁。

    31 引用 • 108 回帖
  • WordPress

    WordPress 是一个使用 PHP 语言开发的博客平台,用户可以在支持 PHP 和 MySQL 数据库的服务器上架设自己的博客。也可以把 WordPress 当作一个内容管理系统(CMS)来使用。WordPress 是一个免费的开源项目,在 GNU 通用公共许可证(GPLv2)下授权发布。

    66 引用 • 114 回帖 • 197 关注
  • SQLite

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

    5 引用 • 7 回帖
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    367 引用 • 1844 回帖 • 3 关注
  • Anytype
    3 引用 • 31 回帖 • 13 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • Love2D

    Love2D 是一个开源的, 跨平台的 2D 游戏引擎。使用纯 Lua 脚本来进行游戏开发。目前支持的平台有 Windows, Mac OS X, Linux, Android 和 iOS。

    14 引用 • 53 回帖 • 553 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖
  • 微服务

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

    96 引用 • 155 回帖 • 1 关注
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖