12306 API 研究

引子

本篇记录 12306 对外暴露的 API 信息, 具有时效性, 仅供学习.

APIs

1.
https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2016-08-20&from_station=WHN&to_station=SNH

余票查询

import requests
import os
from pprint import pprint
from requests.packages.urllib3.exceptions import InsecureRequestWarning


class Train:
    ticket_hash = {
        '商务座': 'swz_num',
        '特等座': 'tz_num',
        '一等座': 'zy_num',
        '二等座': 'ze_num',
        '高级软卧': 'gr_num',
        '软卧': 'rw_num',
        '硬卧': 'yw_num',
        '软座': 'rz_num',
        '硬座': 'yz_num',
        '无座': 'wz_num',
        '其它': 'qt_num'
    }

    def __init__(self, date, from_station, to_station, train_code=None, ticket_type=None):
        # 抑制 12306 自签发的 SSL 证书引发的 warning
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

        self.stationList = self.stationInit()
        self.date = date
        self.from_station = from_station
        self.to_station = to_station
        self.train_code = train_code
        self.ticket_type = ticket_type

    @staticmethod
    def stationInit():
        """
        @bji|北京|BJP|beijing|bj|2
        @拼音缩写三位|站点名称|编码|拼音|拼音缩写|序号
        :return:
        """
        stations = {}
        if not os.path.isfile('station_name.js'):
            res = requests.get(
                'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js',
                verify=False
            )
            with open('station_name.js', 'wb') as fp:
                fp.write(res.content)
        with open('station_name.js', encoding='utf8') as fp:
            data = fp.read()
            data = data.partition('=')[2].strip("'")  # var station_names ='..'
        for station in data.split('@')[1:]:
            items = station.split('|')  # bjb|北京北|VAP|beijingbei|bjb|0
            stations[items[1]] = items[2]
        return stations

    def query(self):
        query_url = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={}' \
                    '&from_station={}&to_station={}'.format(
            self.date,
            self.stationList[self.from_station],
            self.stationList[self.to_station]
        )
        res = requests.get(query_url, verify=False).json()
        pprint(res)
        if res == -1:
            return False
        if not res['data']['flag']:
            return False
        if self.train_code and self.ticket_type:
            for each_train in res['data']['datas']:
                if each_train['station_train_code'] == self.train_code:
                    for each_ticket in self.ticket_type:
                        print(each_ticket + ': ' + each_train[self.ticket_hash[each_ticket]])
        else:
            for each_train in res['data']['datas']:
                print(each_train['station_train_code'])


t = Train('2016-08-20', '武汉', '上海南', 'K121', ['硬卧', '软卧', '硬座', '软座', '无座'])
t.query()

2.
https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=39000D302808&from_station_telecode=AOH&to_station_telecode=ZEK&depart_date=2016-08-20

查询 train_no 指定车次所有经过的站

3.
https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=39000D302808&from_station_no=01&to_station_no=12&seat_types=OMO&train_date=2016-08-19

查询 train_no 指定车次票价
其中, from_station_no, to_station_no 以及 seat_types 来自接口 1

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值