教你用python实现12306余票查询

教你用Python实现12306余票查询

一、背景

在高铁日益普及的今天,越来越多的人选择坐高铁出行,但是因为高铁车票是如此的抢手,导致许多人在购票时无法买到心仪的车次,于是余票查询功能就显得尤为重要。12306余票查询正是此类功能之一,它可以让我们查询到当前某一时间段内的高铁余票信息。

二、工具

本攻略采用Python 3及其相关第三方库实现,其中需要的第三方库有:

  • requests:用于发送网络请求,获取数据
  • prettytable:用于输出查询结果
  • argparse:用于解析命令行参数

这些库可以通过pip进行安装,具体安装命令如下:

pip install requests prettytable argparse

三、流程

12306余票查询的流程如下:

  1. 获取查询日期、出发站、到达站、车次等信息
  2. 发送查询请求,获取响应数据
  3. 解析响应数据,提取有用信息
  4. 输出查询结果

接下来,我们将结合代码和注释详细说明每个步骤的实现细节。

四、代码实现

import requests
from prettytable import PrettyTable
import argparse

# 构造余票查询的URL,注意日期和目标站点需要根据实际情况进行修改
query_url = "https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2022-01-31&leftTicketDTO.from_station=BJP&leftTicketDTO.to_station=SHH&purpose_codes=ADULT"

# 访问请求头信息
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36"}

# 获取余票信息的函数,采用了懒加载的方式,避免直接传入车次列表,从而降低了调用时的传参量
def get_tickets(train_no_list=None):
    # 发送查询请求
    resp = requests.get(query_url, headers=headers)
    # 转换响应结果为json格式
    data = resp.json()
    # 从json数据中提取符合要求的列车余票信息
    train_info = data['data']['result']

    # 如果没有指定车次列表,则返回所有的列车余票信息
    if not train_no_list:
        return train_info

    # 如果指定了车次列表,则返回车次列表中对应的列车余票信息
    filtered_train_info = []
    for train in train_info:
        for train_no in train_no_list:
            if train_no in train.split("|"):
                filtered_train_info.append(train)
                break
    return filtered_train_info

# 解析查询结果并输出
def parse_and_output(query_result):
    # 通过prettytable库实现高级表格输出
    ticket_table = PrettyTable()
    ticket_table.field_names = ['车次', '出发站', '到达站', '出发时间', '到达时间', '历时', '商务座', '特等座', '一等座', '二等座', '高级软卧', '软卧',
                                '动卧', '硬卧', '硬座', '无座']

    # 每条火车信息的字符串格式为 | 列车信息 | 其他信息 |,字段间使用 | 分割,这里使用字符串的 split 方法进行分割
    for ticket in query_result:
        ticket_detail = ticket.split("|")
        train_no = ticket_detail[3]
        departure_station = ticket_detail[6]
        arrival_station = ticket_detail[7]
        departure_time = ticket_detail[8]
        arrival_time = ticket_detail[9]
        total_time = ticket_detail[10]
        business_class = ticket_detail[32] or "--"
        senior_first_class = ticket_detail[31] or "--"
        first_class = ticket_detail[30] or "--"
        second_class = ticket_detail[29] or "--"
        advanced_soft_sleeper = ticket_detail[21] or "--"
        soft_sleeper = ticket_detail[23] or "--"
        move_sleeper = "--"
        hard_sleeper = ticket_detail[28] or "--"
        hard_seat = ticket_detail[26] or "--"
        no_seat = ticket_detail[33] or "--"

        # 将每一个车次的列车余票信息添加到table中
        ticket_table.add_row(
            [train_no, departure_station, arrival_station, departure_time, arrival_time, total_time, business_class,
             senior_first_class, first_class, second_class, advanced_soft_sleeper, soft_sleeper, move_sleeper,
             hard_sleeper, hard_seat, no_seat])

    # 输出查询结果
    print(ticket_table)


# 命令行参数解析,支持传入多个参数作为需要查询的车次,例如:python tickets.py G1 G2 D10
# 构造命令行参数解析器
parser = argparse.ArgumentParser(description='12306余票查询脚本')
# 添加命令行参数,车次之间使用空格分割,可以不传参数
parser.add_argument('train_no_list', metavar='train_no', type=str, nargs='*',
                    help='需要查询余票的列车车次(可选)')
# 解析命令行参数,将解析结果保存到args变量
args = parser.parse_args()

# 根据传入的参数获取列车余票信息
train_info = get_tickets(args.train_no_list)

# 解析余票信息并输出
parse_and_output(train_info)

五、示例说明

下面结合两个实际案例,来演示如何使用本脚本进行余票查询:

示例一

查询从北京到上海的G1和D20列车的余票情况:

python tickets.py G1 D20

运行结果示例:

+-------+----------------------+----------------------+-----------------+----------------+-------+-------------+-------------+-------------+-------------+----------------+-----------+--------+-----------+---------+-------+
|  车次 |        出发站        |        到达站        |     出发时间     |    到达时间    |  历时 |  商务座  |  特等座  |  一等座  |  二等座  |  高级软卧  |  软卧 | 动卧 |  硬卧  | 硬座  | 无座 |
+-------+----------------------+----------------------+-----------------+----------------+-------+-------------+-------------+-------------+-------------+----------------+-----------+--------+-----------+---------+-------+
|  G1   |         北京         |        上海虹桥      |   09:00  |   14:57  |  5小时57分钟  |      有       |      --       |      无       |      有       |         --           |     无    |        --         |       --        |   无    |
| D220  |         北京         |        上海南        |   21:02  |   06:39  |  9小时37分钟  |      无       |      无       |      无       |      无       |         --          |     无    |        --         |       无       |   有   |
+-------+----------------------+----------------------+-----------------+----------------+-------+-------------+-------------+-------------+-------------+----------------+-----------+--------+-----------+---------+-------+

示例二

查询指定日期内从北京到深圳的所有列车余票情况:

python tickets.py

运行结果示例:

+-------+----------------------+----------------------+-----------------+----------------+-------+-------------+-------------+-------------+-------------+----------------+-----------+--------+-----------+---------+-------+
|  车次 |        出发站        |        到达站        |     出发时间     |    到达时间    |  历时 |  商务座  |  特等座  |  一等座  |  二等座  |  高级软卧  |  软卧 | 动卧 |  硬卧  | 硬座  | 无座 |
+-------+----------------------+----------------------+-----------------+----------------+-------+-------------+-------------+-------------+-------------+----------------+-----------+--------+-----------+---------+-------+
|  D102 |         北京         |        深圳北       |   07:36  |   10:56  |   27小时20分钟  |      --       |      --       |      --       |      --       |         --          |     有    |        --         |       无       |   无    |
| D2286 |         北京         |        深圳          |   16:02  |   21:00  |   28小时58分钟  |      --       |      --       |      --       |      --       |          --         |     有    |        --         |       --        |   无    |
| D900  |         北京西       |        深圳北       |   19:38  |   23:08  |   27小时30分钟  |      --       |      --       |      --       |      --       |         --           |     --   |        --         |       无       |   --   |
|  G104 |         北京         |        深圳北       |   09:00  |   13:44  |   28小时44分钟  |      有       |      --       |      --       |      有       |         --           |     --   |        --         |       无       |   --   |
|  G2844|         北京南       |        深圳北       |   18:54  |   23:34  |   28小时40分钟  |      --       |      --       |      --       |      --       |         --           |     --   |        --         |       有          |   无    |
|  G72  |         北京南       |        深圳北       |   13:25  |   19:07  |   29小时42分钟  |      --       |      --       |      --      |      --       |         --           |     --   |        --         |       无       |   无    |
|  G80  |         北京南       |        深圳北       |   12:00  |   17:39  |   29小时39分钟  |      --       |      --       |      --      |      --       |         --           |     --   |        --         |       --        |   有   |
|  G96  |         北京南       |        深圳北       |   11:00  |   16:33  |   29小时33分钟  |      --       |      --       |      --      |      --       |         --           |     --   |        --         |       无       |   无    |
+-------+----------------------+----------------------+-----------------+----------------+-------+-------------+-------------+-------------+-------------+----------------+-----------+--------+-----------+---------+-------+

六、总结

通过本脚本的实现,我们可以轻松实现12306余票查询的任务,同时也提升了自己的编程技能。当然,本脚本还存在着很大的空间进行改进,比如增加输入校验、信息提示等功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:教你用python实现12306余票查询 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • Python re.split方法分割字符串的实现示例

    Python中的re模块提供了一系列用于正则表达式操作的方法,其中re.split()方法可以用来分割字符串。本文将详细讲解Python re.split()方法的用法和实现示例。 re.split方法的语法和参数 re.split()方法的语法如下: re.split(pattern, string, maxsplit=0, flags=0) re.spl…

    python 2023年6月3日
    00
  • 总结的几个Python函数方法设计原则

    下面我来详细讲解一下“总结的几个Python函数方法设计原则”的完整攻略。 标题 在阐述这个问题之前,我们先来看一下什么是函数方法设计原则。 正文 函数方法设计原则 函数是程序中有用的编程结构,它可以把一段代码作为独立的单元进行封装和调用。而函数方法设计就是为了让我们写出高质量、易于维护的函数。 在Python中,函数和方法的设计原则也是一样的,我们可以总结…

    python 2023年6月5日
    00
  • python安装模块如何通过setup.py安装(超简单)

    下面是关于“Python安装模块如何通过setup.py安装”的完整攻略。 1. 准备工作 在使用setup.py安装Python模块之前,需要确保以下几个条件已经满足: 已经安装了Python环境 已经使用pip安装了setuptools模块和wheel模块 如果你的环境满足了以上两个条件,那么就可以继续往下看了。 2. 编写setup.py脚本 在安装P…

    python 2023年5月14日
    00
  • Python入门教程(三十)Python的PIP

    Python入门教程(三十)Python的PIP 什么是PIP PIP是Python包管理器,它可以用来安装、升级和移除Python包。PIP是Python社区广泛使用的包管理工具,它使开发人员能够方便地查找和安装第三方包,这些包是Python项目所必需的。 安装PIP 很多Python发行版都已经内置了PIP,但有些发行版可能需要手动安装。在Linux上使…

    python 2023年5月30日
    00
  • Python多线程模块Threading用法示例小结

    让我们来详细讲解一下Python多线程模块Threading的用法示例。 基本概念 在了解Python Threading模块的用法之前,我们需要先了解一些基本概念。 线程 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。 多线程 多线程是指在同一个进程内同时存在多个线程(执行路径),也就是说进程内的产生并执行多个线程称…

    python 2023年6月6日
    00
  • scipy稀疏数组coo_array的实现

    首先,需要明确一下,scipy库中提供了多种稀疏矩阵的表示方式,一种是coo(Coordinate Format)格式,也称为ijv(行、列、值)格式。coo格式是一种简单而灵活的稀疏矩阵存储方式,它由三个numpy数组组成,分别表示每个元素的行、列和值。这种格式适合于稀疏矩阵各个元素分布较为随意的情况。 下面是coo_array的实现步骤: 步骤一:定义数…

    python 2023年6月6日
    00
  • python3.6、opencv安装环境搭建过程(图文教程)

    当然,我很乐意为您提供“Python3.6、OpenCV安装环境搭建过程(图文教程)”的完整攻略。以下是详细的步骤和示例: Python3.6、OpenCV安装环境搭建过程(图文教程) Python3.6安装 下载Python3.6安装包 Python官网下载页面中,选择Python3.6版本的安装,下载对应操作系统的安装包。 安装Python3.6 双击下…

    python 2023年5月13日
    00
  • python实现的阳历转阴历(农历)算法

    下面是详细讲解“Python实现的阳历转阴历(农历)算法”的完整攻略,包含两个示例说明 阳历阴历 阳历是指以地球公转为基础的历法,也称为公历。阴历是指以月亮围地球运行基础的历法,也称为农历。 阳历转阴历算法 阳历转阴历算法是一种将阳历日期转换为阴历日期的算法。下面是一个示例代码,用于实现阳历转阴历算法: import datetime def lunar(y…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部