使用Python實(shí)現(xiàn)火車票查詢系統(tǒng)(帶界面)
導(dǎo)語
周末、假期來了,七夕也快到了,又到一年中最一票難求的時(shí)候了!
那些假期想回家、過節(jié)異地戀的小可愛們,能準(zhǔn)時(shí)搶到回家(約會(huì)對(duì)象)的城市票嘛?
為了讓大家盡早的和親朋好友家人團(tuán)聚,小編今年很英勇的出來提醒大家早點(diǎn)兒搶火車票啦!
(時(shí)不我待,有票的時(shí)候妖提前買好啦~不然到時(shí)候在賣科能沒票了滴)
特地為大家寫了一款代碼基于Python的有界面火車票查詢系統(tǒng),隨時(shí)隨地查詢,不然去專門購(gòu)票的地方問,沒票白跑一趟也麻煩了——如果有票記得早點(diǎn)兒買買買哈!
注:需要不需要都要學(xué)一下,萬一哪天就用上了呢,學(xué)到了也不虧哈!
一、運(yùn)行環(huán)境
1)小編使用的環(huán)境:Python3、Pycharm社區(qū)版、requests、PyQt5模塊、部分自帶就不一一展示啦。
模塊安裝:pip install -i https://pypi.douban.com/simple/+模塊名
二、代碼展示
1)爬取數(shù)據(jù)
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) # 匹配中文和對(duì)應(yīng)的英文 stations = dict(stations) # 轉(zhuǎn)化成字典 # pprint(stations) # 以列的形式打印出來
2)主程序
''' 火車票查詢系統(tǒng) ''' __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('火車票查詢系統(tǒng)') #self.setGeometry(40,80,1500,720) #第一部分,輸入出發(fā)地、目的地和日期 controlsLayout = QGridLayout() #柵格布局 self.label1 = QLabel("出發(fā)地:") 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 = ["車次","車站","時(shí)間","歷時(shí)","商務(wù)座","一等座","二等座","高級(jí)軟臥","軟臥","動(dòng)臥","硬臥","軟座","硬座","無座","其他"] 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)#設(shè)定樣式 #self.table.setShowGrid(False) #取消網(wǎng)格線 #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): #關(guān)閉時(shí)彈窗提示 reply = QMessageBox.question(self, '警告', '查詢記錄不會(huì)被保存,\n確認(rè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())) #反轉(zhuǎn)字典 from_s = self.Editlabel1.text() #獲取文本框內(nèi)容 to_s = self.Editlabel2.text() if (from_s in stations.keys()) and (to_s in stations.keys()): f = stations[from_s] # 通過字典轉(zhuǎn)化為車站對(duì)應(yīng)的縮寫字母 t = stations[to_s] # 通過字典轉(zhuǎn)化為車站對(duì)應(yīng)的縮寫字母 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") # 這個(gè)網(wǎng)站是有安全警告的,這段代碼可以忽略警告 r = requests.get(url, verify=False) raw_trains = r.json()['data']['result'] # 獲取車次信息 # print(raw_trains) num = len(raw_trains) # 獲取車次數(shù)目 # print('共查詢到%d個(gè)車次信息'%num) self.message.setText("共查詢到%d個(gè)車次信息"%num) if raw_trains == []: QMessageBox.warning(self, "提示", "暫無所查詢的車次信息!") i=0 self.table.setRowCount(num) self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) #關(guān)閉水平滾動(dòng)條 for raw_train in raw_trains: # split分割之后得到的是一個(gè)列表 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]] #出發(fā)地,通過字典轉(zhuǎn)換 mdd = stations_fz[data_list[7]] #目的地 fctime = data_list[8] # 發(fā)車時(shí)間 ddtime = data_list[9] # 到達(dá)時(shí)間 lishi = data_list[10] # 歷時(shí) shangwuzuo = data_list[32] or "--" # 商務(wù)座/特等座 yidengzuo = data_list[31] or "--" # 一等座 erdengzuo = data_list[30] or "--" # 二等座 gjruanwo = data_list[21] or "--" # 高級(jí)軟臥 ruanwo = data_list[23] or "--" # 軟臥 dongwo = data_list[33] or "--" # 動(dòng)臥 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:高級(jí)軟臥 pr_gjrw = raw_prices['A6'] else: pr_gjrw = '' if 'A9' in raw_prices.keys(): # A9:商務(wù)座,特等座 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:動(dòng)臥 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) #設(shè)置行高 i=i+1 #self.table.setSpan(0, 8, 2, 1) #合并單元格 else: if from_s not in stations.keys(): # print('請(qǐng)輸入正確的出發(fā)地') QMessageBox.warning(self,"提示","請(qǐng)輸入正確的出發(fā)地!") if to_s not in stations.keys(): # print('請(qǐng)輸入正確的目的地') QMessageBox.warning(self,"提示","請(qǐng)輸入正確的目的地!") if __name__ == '__main__': app = QApplication(sys.argv) table = TableSheet() table.show() sys.exit(app.exec_())
三、效果展示
1)界面效果
2)時(shí)間日期
?
3)記錄刪除
到此這篇關(guān)于使用Python實(shí)現(xiàn)火車票查詢系統(tǒng)(帶界面)的文章就介紹到這了,更多相關(guān)Python火車票查詢系統(tǒng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python3.4學(xué)習(xí)筆記之類型判斷,異常處理,終止程序操作小結(jié)
這篇文章主要介紹了Python3.4學(xué)習(xí)筆記之類型判斷,異常處理,終止程序操作,結(jié)合具體實(shí)例形式分析了Python3.4模塊導(dǎo)入、異常處理、退出程序等相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2019-03-03pandas中read_csv、rolling、expanding用法詳解
這篇文章主要介紹了pandas中read_csv、rolling、expanding用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04Python函數(shù)isalnum用法示例小結(jié)
isalnum()函數(shù)是Python中的一個(gè)內(nèi)置函數(shù),用于判斷字符串是否只由數(shù)字和字母組成,其內(nèi)部實(shí)現(xiàn)原理比較簡(jiǎn)單,只需遍歷字符串中的每一個(gè)字符即可,這篇文章主要介紹了Python函數(shù)isalnum用法介紹,需要的朋友可以參考下2024-01-01Python實(shí)現(xiàn)aes加密解密多種方法解析
這篇文章主要介紹了Python實(shí)現(xiàn)aes加密解密多種方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05