导语
周末、假期来了,七夕也快到了,又到一年中最一票难求的时候了!
那些假期想回家、过节异地恋的小可爱们,能准时抢到回家(约会对象)的城市票嘛?
所有文章完整的素材+源码都在
粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。
为了让大家尽早的和亲朋好友家人团聚,小编今年很英勇的出来提醒大家早点儿抢火车票啦!
(时不我待,有票的时候妖提前买好啦~不然到时候在卖科能没票了滴)
特地为大家写了一款代码基于Python的有界面火车票查询系统,随时随地查询,不然去专门购
票的地方问,没票白跑一趟也麻烦了——如果有票记得早点儿买买买哈!
注:需要不需要都要学一下,万一哪天就用上了呢,学到了也不亏哈!
正文
一、运行环境
小编使用的环境:Python3、Pycharm社区版、requests、PyQt5模块、部分自带就不一一
展示啦。
模块安装:pip install -i https://pypi.douban.com/simple/+模块名
二、代码展示
1)爬取数据
import reimport urllibfrom urllib import request# from pprint import pprinturl = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js" />2)主程序 '''火车票查询系统'''__author__ = 'Scorpio'import sysfrom PyQt5.QtCore import Qt,QDateTimefrom PyQt5.QtWidgets import QWidget,QMessageBox,QApplication,QLabel,QTableWidget,QLineEdit,QHBoxLayout,QGridLayout,QVBoxLayout,QPushButton,QTableWidgetItem,QFrame,QDateTimeEditfrom PyQt5.QtGui import QFont,QColor,QBrushfrom get_stations import stationsimport warningsimport requestsclass 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=0self.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_nofrom_s_no = data_list[16] #from_station_noto_s_no = data_list[17] #to_station_noseat_type = data_list[35] #seat_typestra_date = d#train_datecheci = 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_dater1 = 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_())
三、效果展示
1)界面效果
2)时间日期
3)记录删除
更多隐藏效果等你来体验啦~
总结
好啦!文章到这里也正式结束了滴!最后,预祝大家之后的假期(节日)愉快,旅途愉快,都能
如愿以偿啦~老规矩源码素材啥的
完整的免费源码领取处:找我吖!文末公众hao可自行领取,滴滴我也可!
推荐往期文章——
项目1.0 漫天飞雪小程序
Python小程序:你看?这千年难遇的雪景——简直“美到犯规”【满屏雪花飞舞】
项目1.1 辞职小程序
【附Python版教学】“那些年用过的奇葩辞职理由”哈哈哈,看完笑掉牙。
项目1.3 视频播放器
用了都说好的Python专属无广告视频播放器,良心到想为它疯狂打call
项目3.2 自动换壁纸
【Python高级技能】超炫酷,电脑每天自动换壁纸,这个神器适合你。
项目4.7 电影订票选座系统
【Python订票系统】这才是看电影选座的正确方法,原来我们都上当了~(选座位、一键购票)
文章汇总——
项目1.0 Python—2021 |已有文章汇总 | 持续更新,直接看这篇就够了
(更多内容+源码都在文章汇总哦!!欢迎阅读~)