教你用Python实现12306余票查询
一、背景
在高铁日益普及的今天,越来越多的人选择坐高铁出行,但是因为高铁车票是如此的抢手,导致许多人在购票时无法买到心仪的车次,于是余票查询功能就显得尤为重要。12306余票查询正是此类功能之一,它可以让我们查询到当前某一时间段内的高铁余票信息。
二、工具
本攻略采用Python 3及其相关第三方库实现,其中需要的第三方库有:
- requests:用于发送网络请求,获取数据
- prettytable:用于输出查询结果
- argparse:用于解析命令行参数
这些库可以通过pip进行安装,具体安装命令如下:
pip install requests prettytable argparse
三、流程
12306余票查询的流程如下:
- 获取查询日期、出发站、到达站、车次等信息
- 发送查询请求,获取响应数据
- 解析响应数据,提取有用信息
- 输出查询结果
接下来,我们将结合代码和注释详细说明每个步骤的实现细节。
四、代码实现
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技术站