使用Python实现火车票查询系统(带界面)

作者:木木子学python 时间:2022-04-26 04:14:47 

导语

周末、假期来了,七夕也快到了,又到一年中最一票难求的时候了!

那些假期想回家、过节异地恋的小可爱们,能准时抢到回家(约会对象)的城市票嘛?

为了让大家尽早的和亲朋好友家人团聚,小编今年很英勇的出来提醒大家早点儿抢火车票啦!

(时不我待,有票的时候妖提前买好啦~不然到时候在卖科能没票了滴)

特地为大家写了一款代码基于Python的有界面火车票查询系统,随时随地查询,不然去专门购票的地方问,没票白跑一趟也麻烦了——如果有票记得早点儿买买买哈!

注:需要不需要都要学一下,万一哪天就用上了呢,学到了也不亏哈!

使用Python实现火车票查询系统(带界面)

一、运行环境

1)小编使用的环境:Python3、Pycharm社区版、requests、PyQt5模块、部分自带就不一一展示啦。

模块安装:pip install -i https://pypi.douban.com/simple/+模块名 

二、代码展示

1)爬取数据

import re
import urllib
from urllib import request
# from pprint import pprint
url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9048'
req = urllib.request.Request(url)
r = urllib.request.urlopen(req).read().decode('utf-8')
stations =re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)',r)    # 匹配中文和对应的英文
stations = dict(stations)     # 转化成字典
# pprint(stations)      # 以列的形式打印出来

2)主程序

'''
火车票查询系统
'''
__author__ = 'Scorpio'
import sys
from PyQt5.QtCore import Qt,QDateTime
from PyQt5.QtWidgets import QWidget,QMessageBox,QApplication,QLabel,QTableWidget,QLineEdit,QHBoxLayout,QGridLayout,QVBoxLayout,QPushButton,QTableWidgetItem,QFrame,QDateTimeEdit
from PyQt5.QtGui import QFont,QColor,QBrush
from get_stations import stations
import warnings
import requests
class TableSheet(QWidget):
   def __init__(self):
       super().__init__()
       self.initUi()

def initUi(self):
       #self.setWindowFlags(Qt.WindowCloseButtonHint && Qt.WindowMinimizeButtonHint)
       #self.setWindowFlags(Qt.WindowMinimizeButtonHint)
       self.setWindowTitle('火车票查询系统')
       #self.setGeometry(40,80,1500,720)
       #第一部分,输入出发地、目的地和日期
       controlsLayout = QGridLayout()      #栅格布局
       self.label1 = QLabel("出发地:")
       self.Editlabel1 = QLineEdit()
       self.label2 = QLabel("目的地:")
       self.Editlabel2 = QLineEdit()
       self.label3 = QLabel("乘车日期:")

self.Editlabel3 = QDateTimeEdit()
       now = QDateTime.currentDateTime()
       #print(now)
       self.Editlabel3.setDateTime(now)
       self.Editlabel3.setDisplayFormat("yyyy-MM-dd")      #小写m为分钟
       self.Editlabel3.setCalendarPopup(True)

self.buttonOK = QPushButton("确定")

controlsLayout.addWidget(QLabel(""),0,0,1,6)
       self.message = QLabel("暂未查询车次信息!")
       controlsLayout.addWidget(self.message,0,7,1,4)

controlsLayout.addWidget(self.label1,0,11,1,1)
       controlsLayout.addWidget(self.Editlabel1,0,12,1,2)
       controlsLayout.addWidget(QLabel(" "),0,14,1,1)

controlsLayout.addWidget(self.label2,0,15,1,1)
       controlsLayout.addWidget(self.Editlabel2,0,16,1,2)
       controlsLayout.addWidget(QLabel(" "),0,18,1,1)

controlsLayout.addWidget(self.label3,0,19,1,1)
       controlsLayout.addWidget(self.Editlabel3,0,20,1,2)
       controlsLayout.addWidget(QLabel(" "),0,22,1,1)

controlsLayout.addWidget(self.buttonOK,0,23,1,1)
       controlsLayout.addWidget(QLabel(" "),0,25,1,8)

#第二部分,显示查询到的车次信息
       horizontalHeader = ["车次","车站","时间","历时","商务座","一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他"]
       self.table = QTableWidget()
       self.table.setColumnCount(15)
       self.table.setRowCount(0)       #初始化为0行
       self.table.setHorizontalHeaderLabels(horizontalHeader)
       self.table.setEditTriggers(QTableWidget.NoEditTriggers)     #不能编辑
       self.table.setSelectionBehavior(QTableWidget.SelectRows)    #选中整行
       self.table.setSelectionMode(QTableWidget.SingleSelection)
       for index in range(self.table.columnCount()):
           headItem = self.table.horizontalHeaderItem(index)
           headItem.setFont(QFont("song", 12, QFont.Bold))
           headItem.setForeground(QBrush(Qt.gray))
           headItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
       #self.table.setFrameShape(QFrame.HLine)#设定样式
       #self.table.setShowGrid(False) #取消网格线
       #self.table.verticalHeader().setVisible(False) #隐藏垂直表头
       #row_count = self.table.rowCount()
       #self.table.setColumnWidth(0,200)
       mainLayout = QHBoxLayout()
       mainLayout.addWidget(self.table)
       layout = QVBoxLayout()
       layout.addLayout(controlsLayout)
       layout.addLayout(mainLayout)
       self.setLayout(layout)
       self.buttonOK.clicked.connect(self.showMessage)
       self.showMaximized()

def closeEvent(self, event):        #关闭时弹窗提示
       reply = QMessageBox.question(self, '警告', '查询记录不会被保存,\n确认退出?',QMessageBox.Yes,QMessageBox.No)
       if reply == QMessageBox.Yes:
           event.accept()
       else:
           event.ignore()

def showMessage(self):      #显示查询信息
       stations_fz = dict(map(lambda t:(t[1],t[0]), stations.items()))     #反转字典
       from_s = self.Editlabel1.text()   #获取文本框内容
       to_s = self.Editlabel2.text()
       if (from_s in stations.keys()) and (to_s in stations.keys()):
           f = stations[from_s]     # 通过字典转化为车站对应的缩写字母
           t = stations[to_s]       # 通过字典转化为车站对应的缩写字母
           date = self.Editlabel3.text()
           d = str(date)
           # print(d)
           # print('正在查询' + from_s + '至' + to_s + '的列车...')
           url = 'https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=' + d + '&leftTicketDTO.from_station=' + f + '&leftTicketDTO.to_station=' + t +'&purpose_codes=ADULT'
           # print(url)
           warnings.filterwarnings("ignore")  # 这个网站是有安全警告的,这段代码可以忽略警告
           r = requests.get(url, verify=False)
           raw_trains = r.json()['data']['result']     # 获取车次信息
           # print(raw_trains)
           num = len(raw_trains)       # 获取车次数目
           # print('共查询到%d个车次信息'%num)
           self.message.setText("共查询到%d个车次信息"%num)
           if raw_trains == []:
               QMessageBox.warning(self, "提示", "暂无所查询的车次信息!")
           i=0
           self.table.setRowCount(num)
           self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)      #关闭水平滚动条
           for raw_train in raw_trains:
               # split分割之后得到的是一个列表
               data_list = raw_train.split("|")
               # print(data_list)
               tra_no = data_list[2]     #train_no
               from_s_no = data_list[16]   #from_station_no
               to_s_no = data_list[17]     #to_station_no
               seat_type = data_list[35]       #seat_types
               tra_date = d            #train_date
               checi = data_list[3]     # 车次
               cfd = stations_fz[data_list[6]]      #出发地,通过字典转换
               mdd = stations_fz[data_list[7]]      #目的地
               fctime = data_list[8]    # 发车时间
               ddtime = data_list[9]    # 到达时间
               lishi = data_list[10]    # 历时
               shangwuzuo = data_list[32] or "--"    # 商务座/特等座
               yidengzuo = data_list[31] or "--"     # 一等座
               erdengzuo = data_list[30] or "--"     # 二等座
               gjruanwo = data_list[21] or "--"      # 高级软卧
               ruanwo = data_list[23] or "--"        # 软卧
               dongwo = data_list[33] or "--"        # 动卧
               yingwo = data_list[28] or "--"        # 硬卧
               ruanzuo = data_list[24] or "--"       # 软座
               yingzuo = data_list[29] or "--"       # 硬座
               wuzuo = data_list[26] or "--"         # 无座
               others = data_list[22] or "--"        # 其他

price_url = "https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no="+tra_no+"&from_station_no="+from_s_no+"&to_station_no="+to_s_no+"&seat_types="+seat_type+"&train_date="+tra_date
               r1 = requests.get(price_url, verify=False)
               # print(price_url)
               raw_prices = r1.json()['data']  # 获取车次信息
               if 'A1' in raw_prices.keys():           #A1:硬座
                   pr_yz = raw_prices['A1']
               else:
                   pr_yz = ''
               if 'A2' in raw_prices.keys():           # A2:软座
                   pr_rz = raw_prices['A2']
               else:
                   pr_rz = ''
               if 'A3' in raw_prices.keys():           # A3:硬卧
                   pr_yw = raw_prices['A3']
               else:
                   pr_yw = ''
               if 'A4' in raw_prices.keys():           # A4:软卧
                   pr_rw = raw_prices['A4']
               else:
                   pr_rw = ''
               if 'A6' in raw_prices.keys():           # A6:高级软卧
                   pr_gjrw = raw_prices['A6']
               else:
                   pr_gjrw = ''
               if 'A9' in raw_prices.keys():           # A9:商务座,特等座
                   pr_swz = raw_prices['A9']
               else:
                   pr_swz = ''
               if 'WZ' in raw_prices.keys():           # WZ:无座
                   pr_wz = raw_prices['WZ']
               else:
                   pr_wz = ''
               if 'M' in raw_prices.keys():            # M:一等座
                   pr_ydz = raw_prices['M']
               else:
                   pr_ydz = ''
               if 'O' in raw_prices.keys():            # O:二等座
                   pr_edz = raw_prices['O']
               else:
                   pr_edz = ''
               if 'F' in raw_prices.keys():            # F:动卧
                   pr_dw = raw_prices['F']
               else:
                   pr_dw = ''
               # print(pr_yz,pr_rz,pr_yw,pr_rw,pr_gjrw,pr_swz,pr_wz,pr_ydz,pr_edz,pr_dw)
               NewItem=QTableWidgetItem(checi)
               NewItem.setForeground(QColor(Qt.red))
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)  #垂直居中
               self.table.setItem(i,0,NewItem)

NewItem=QTableWidgetItem(cfd +'\n-\n'+mdd)
               NewItem.setFont(QFont("song", 9, QFont.Bold))
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,1,NewItem)

NewItem=QTableWidgetItem(fctime+'\n-\n'+ddtime)
               NewItem.setFont(QFont("song", 9, QFont.Bold))
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,2,NewItem)

NewItem=QTableWidgetItem(lishi)
               NewItem.setFont(QFont("song", 9, QFont.Bold))
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,3,NewItem)

NewItem=QTableWidgetItem(shangwuzuo+'\n'+ pr_swz)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,4,NewItem)

NewItem=QTableWidgetItem(yidengzuo+'\n'+ pr_ydz)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,5,NewItem)

NewItem=QTableWidgetItem(erdengzuo+'\n'+ pr_edz)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,6,NewItem)

NewItem=QTableWidgetItem(gjruanwo+'\n'+ pr_gjrw)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,7,NewItem)

NewItem=QTableWidgetItem(ruanwo+'\n'+ pr_rw)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,8,NewItem)

NewItem=QTableWidgetItem(dongwo+'\n'+ pr_dw)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,9,NewItem)

NewItem=QTableWidgetItem(yingwo+'\n'+ pr_yw)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,10,NewItem)

NewItem=QTableWidgetItem(ruanzuo+'\n'+ pr_rz)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,11,NewItem)

NewItem=QTableWidgetItem(yingzuo+'\n'+ pr_yz)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,12,NewItem)

NewItem=QTableWidgetItem(wuzuo+'\n'+ pr_wz)
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,13,NewItem)

NewItem=QTableWidgetItem(others+'\n'+'')
               NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
               self.table.setItem(i,14,NewItem)

self.table.setRowHeight(i, 60)      #设置行高

i=i+1
           #self.table.setSpan(0, 8, 2, 1)     #合并单元格
       else:
           if from_s not in stations.keys():
               # print('请输入正确的出发地')
               QMessageBox.warning(self,"提示","请输入正确的出发地!")
           if to_s not in stations.keys():
               # print('请输入正确的目的地')
               QMessageBox.warning(self,"提示","请输入正确的目的地!")
if __name__ == '__main__':
   app = QApplication(sys.argv)
   table = TableSheet()
   table.show()
   sys.exit(app.exec_())

三、效果展示

使用Python实现火车票查询系统(带界面)

1)界面效果

使用Python实现火车票查询系统(带界面)

2)时间日期


使用Python实现火车票查询系统(带界面)

3)记录删除

使用Python实现火车票查询系统(带界面)

来源:https://juejin.cn/post/7123609345790591006

标签:Python,火车票,查询
0
投稿

猜你喜欢

  • JS重现80后儿时经典拼板(模板)游戏

    2011-09-11 18:36:46
  • Python使用enumerate获取迭代元素下标

    2023-03-05 01:46:31
  • Python Pandas 修改表格数据类型 DataFrame 列的顺序案例

    2023-02-27 17:47:37
  • 深度解析Django REST Framework 批量操作

    2021-05-18 03:03:21
  • python处理二进制数据的方法

    2022-09-08 06:20:09
  • python字符串string的内置方法实例详解

    2022-06-14 01:10:23
  • python小程序之4名牌手洗牌发牌问题解析

    2023-08-28 04:06:20
  • Python通过递归获取目录下指定文件代码实例

    2021-02-24 15:08:51
  • python实现图片批量压缩

    2022-01-20 03:03:20
  • Python 图片文字识别的实现之PaddleOCR

    2022-03-12 19:07:58
  • javascript禁用Tab键脚本实例

    2023-10-13 10:53:58
  • python scatter函数用法实例详解

    2021-12-17 11:51:50
  • Python+django实现简单的文件上传

    2021-08-15 03:11:25
  • Go语言中使用反射的方法

    2023-07-22 22:31:48
  • Python深拷贝浅拷贝图文示例清晰整理

    2022-05-05 11:26:40
  • php比较两个指定的日期的实例讲解

    2023-06-13 12:11:29
  • 前端模板引擎

    2010-07-27 12:33:00
  • Python 中的 global 标识对变量作用域的影响

    2021-11-24 00:16:47
  • Python实现返回数组中第i小元素的方法示例

    2021-12-23 14:58:44
  • 在Pytorch中计算卷积方法的区别详解(conv2d的区别)

    2021-02-12 01:01:03
  • asp之家 网络编程 m.aspxhome.com