first commit

main
chengbo20031015 9 months ago
parent f5f83b57cf
commit ff3e02dd06

@ -0,0 +1,200 @@
import tkinter as tk #创建图形用户界面的库
from tkinter import ttk #提供一些更为现代的组件
from tkinter import messagebox #提供一个用于显示消息框的简单接口
import requests #用于进行http请求来获取请12306网站数据
import prettytable as pt#用来创建漂亮的文本表格
import json#处理JSON数据来获取城市车站信息
import datetime#处理日期和时间
# 验证用户输入的城市名称和日期是否有效
def validate_inputs(from_city, to_city, date):
"""验证用户输入的城市名称和日期是否有效"""
# 检查城市名称是否为非空字符串
if not from_city or not to_city:
messagebox.showerror("错误", "城市名称不能为空。")
return False
# 检查日期是否为有效的YYYY-MM-DD格式
if not is_valid_date(date):
messagebox.showerror("错误", "日期格式错误,应为 YYYY-MM-DD。")
return False
return True
def is_valid_date(date_str):
"""检查日期字符串是否为有效的YYYY-MM-DD格式"""
try:
# 尝试将字符串转换为日期
datetime.datetime.strptime(date_str, '%Y-%m-%d')
return True
except ValueError:
return False
# 根据用户输入的出发城市、目的城市和日期来搜索列车
def search_trains():
from_city = from_city_combobox.get()
to_city = to_city_combobox.get()
date = date_entry.get()
train_type = train_type_combobox.get()
# 验证输入:用户输入的出发城市、目的城市和日期无效,则停止执行 search_trains 函数,并返回 None。
if not validate_inputs(from_city, to_city, date):
return
# 读取城市文件 -> 返回json字符串
try:
with open('city.json', 'r', encoding='utf-8') as f:
city_data = json.load(f)
except FileNotFoundError:
messagebox.showerror("错误", "城市数据文件不存在,请确保 city.json 文件在当前目录下。")
return
except json.JSONDecodeError:
messagebox.showerror("错误", "城市数据文件格式错误,请确保 city.json 文件内容为有效的 JSON 格式。")
return
# 构造URL
url = f'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={date}&leftTicketDTO.from_station={city_data[from_city]}&leftTicketDTO.to_station={city_data[to_city]}&purpose_codes=ADULT'
# 向指定的URL发送一个带有特定头信息的GET请求并获取服务器的响应
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0',
'Cookie': '_uab_collina=171195922365279549520858; JSESSIONID=19E602A91EBCFCD88A8BBDF5DABDE80F; _jc_save_wfdc_flag=dc; _jc_save_fromStation=%u682A%u6D32%2CZZQ; _jc_save_toStation=%u957F%u6C99%2CCSQ; BIGipServerotn=1978138890.24610.0000; BIGipServerpassport=837288202.50215.0000; guidesStatus=off; highContrastMode=defaltMode; cursorStatus=off; route=495c805987d0f5c8c84b14f60212447d; _jc_save_fromDate=2024-05-27; _jc_save_toDate=2024-05-27'
}
response = requests.get(url=url, headers=headers)
# 检查请求状态
if response.status_code != 200: # 判断http响应状态码是否成功
messagebox.showerror("错误", f"请求失败,状态码: {response.status_code}")
return
# 解析数据
try:
json_data = response.json()
result = json_data['data']['result']
except (KeyError, json.JSONDecodeError):
messagebox.showerror("错误", "解析数据失败,可能是服务器返回格式错误。")
return
# 创建 PrettyTable 表格
tb = pt.PrettyTable()
tb.field_names = [
'序号',
'车次',
'出发时间',
'到达时间',
'耗时',
'特等座',
'一等',
'二等',
'软卧',
'硬卧',
'硬座',
'无座',
]
page = 1
# 填充表格数据
for i in result:
index = i.split('|')
num = index[3]
#根据车次类型进行筛选
train_num = index[3]
start_time = index[8]
end_time = index[9]
use_time = index[10]
topGrade = index[32]
first_class = index[31]
second_class = index[30]
hard_sleeper = index[28]
hard_seat = index[29]
no_seat = index[26]
soft_sleeper = index[23]
# 根据车次类型筛选
if train_type != "全部" and train_type not in train_num:
continue
tb.add_row([
page,
num,
start_time,
end_time,
use_time,
topGrade,
first_class,
second_class,
soft_sleeper,
hard_sleeper,
hard_seat,
no_seat,
])
page += 1
# 显示表格
result_text.config(state=tk.NORMAL)
result_text.delete('1.0', tk.END)
result_text.insert(tk.END, str(tb))
result_text.config(state=tk.DISABLED)
# 创建主窗口
root = tk.Tk()
root.title("火车票查询")
# 创建车次类型选择的下拉列表
train_type_label = ttk.Label(root, text="车次类型:")
train_type_label.grid(row=3, column=0, padx=5, pady=5, sticky="e")
train_type_combobox = ttk.Combobox(root, values=["全部", "G","S","D", "T", "K"])
train_type_combobox.grid(row=3, column=1, padx=5, pady=5)
train_type_combobox.current(0)
# 创建出发城市输入框和标签
from_city_label = ttk.Label(root, text="出发城市:")
from_city_label.grid(row=0, column=0, padx=5, pady=5, sticky="e")
from_city_combobox = ttk.Combobox(root, values=[])
from_city_combobox.grid(row=0, column=1, padx=5, pady=5)
# 创建目的城市输入框和标签
to_city_label = ttk.Label(root, text="目的城市:")
to_city_label.grid(row=1, column=0, padx=5, pady=5, sticky="e")
to_city_combobox = ttk.Combobox(root, values=[])
to_city_combobox.grid(row=1, column=1, padx=5, pady=5)
# 创建出发日期输入框和标签
date_label = ttk.Label(root, text="出发日期:")
date_label.grid(row=2, column=0, padx=5, pady=5, sticky="e")
date_entry = ttk.Entry(root)
date_entry.grid(row=2, column=1, padx=5, pady=5)
# 创建查询按钮
search_button = ttk.Button(root, text="查询", command=search_trains)
search_button.grid(row=10, columnspan=2, padx=5, pady=5)
# 创建显示结果的文本框
result_text = tk.Text(root, height=20, width=100)
result_text.grid(row=4, columnspan=2, padx=5, pady=5)
result_text.config(state=tk.DISABLED)
# 创建欢迎文本框
welcome_label = ttk.Label(root, text="欢迎来到cb的查票系统")
# 设置字体大小
welcome_label.config(font=("微软雅黑", 20)) # 这里使用了微软雅黑字体字体大小为20
welcome_label.grid(row=0, column=0, padx=5, pady=5, sticky="w")# 添加到左上角
# 更新城市下拉列表
def update_city_comboboxes():
cities = list(city_data.keys())
cities.sort()
from_city_combobox['values'] = cities
to_city_combobox['values'] = cities
# 初始化城市数据
try:
with open('city.json', 'r', encoding='utf-8') as f:
city_data = json.load(f)
update_city_comboboxes()
except FileNotFoundError:
messagebox.showerror("错误", "城市数据文件不存在,请确保 city.json 文件在当前目录下。")
except json.JSONDecodeError:
messagebox.showerror("错误", "城市数据文件格式错误,请确保 city.json 文件内容为有效的 JSON 格式。")
root.mainloop()

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save