• 【Python界面化小程序】注意 | 假期火车票查询系统已完成啦,出行注意看这里哦→


    导语

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

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

     所有文章完整的素材+源码都在👇👇

    粉丝白嫖源码福利,请移步至CSDN社区或文末公众hao即可免费。

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

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

    特地为大家写了一款代码基于Python的有界面火车票查询系统,随时随地查询,不然去专门购

    票的地方问,没票白跑一趟也麻烦了——如果有票记得早点儿买买买哈!

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

    正文

    一、运行环境

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

    展示啦。

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

    二、代码展示

    1)爬取数据

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

    2)主程序

    1. '''
    2. 火车票查询系统
    3. '''
    4. __author__ = 'Scorpio'
    5. import sys
    6. from PyQt5.QtCore import Qt,QDateTime
    7. from PyQt5.QtWidgets import QWidget,QMessageBox,QApplication,QLabel,QTableWidget,QLineEdit,QHBoxLayout,QGridLayout,QVBoxLayout,QPushButton,QTableWidgetItem,QFrame,QDateTimeEdit
    8. from PyQt5.QtGui import QFont,QColor,QBrush
    9. from get_stations import stations
    10. import warnings
    11. import requests
    12. class TableSheet(QWidget):
    13. def __init__(self):
    14. super().__init__()
    15. self.initUi()
    16. def initUi(self):
    17. #self.setWindowFlags(Qt.WindowCloseButtonHint && Qt.WindowMinimizeButtonHint)
    18. #self.setWindowFlags(Qt.WindowMinimizeButtonHint)
    19. self.setWindowTitle('火车票查询系统')
    20. #self.setGeometry(40,80,1500,720)
    21. #第一部分,输入出发地、目的地和日期
    22. controlsLayout = QGridLayout() #栅格布局
    23. self.label1 = QLabel("出发地:")
    24. self.Editlabel1 = QLineEdit()
    25. self.label2 = QLabel("目的地:")
    26. self.Editlabel2 = QLineEdit()
    27. self.label3 = QLabel("乘车日期:")
    28. self.Editlabel3 = QDateTimeEdit()
    29. now = QDateTime.currentDateTime()
    30. #print(now)
    31. self.Editlabel3.setDateTime(now)
    32. self.Editlabel3.setDisplayFormat("yyyy-MM-dd") #小写m为分钟
    33. self.Editlabel3.setCalendarPopup(True)
    34. self.buttonOK = QPushButton("确定")
    35. controlsLayout.addWidget(QLabel(""),0,0,1,6)
    36. self.message = QLabel("暂未查询车次信息!")
    37. controlsLayout.addWidget(self.message,0,7,1,4)
    38. controlsLayout.addWidget(self.label1,0,11,1,1)
    39. controlsLayout.addWidget(self.Editlabel1,0,12,1,2)
    40. controlsLayout.addWidget(QLabel(" "),0,14,1,1)
    41. controlsLayout.addWidget(self.label2,0,15,1,1)
    42. controlsLayout.addWidget(self.Editlabel2,0,16,1,2)
    43. controlsLayout.addWidget(QLabel(" "),0,18,1,1)
    44. controlsLayout.addWidget(self.label3,0,19,1,1)
    45. controlsLayout.addWidget(self.Editlabel3,0,20,1,2)
    46. controlsLayout.addWidget(QLabel(" "),0,22,1,1)
    47. controlsLayout.addWidget(self.buttonOK,0,23,1,1)
    48. controlsLayout.addWidget(QLabel(" "),0,25,1,8)
    49. #第二部分,显示查询到的车次信息
    50. horizontalHeader = ["车次","车站","时间","历时","商务座","一等座","二等座","高级软卧","软卧","动卧","硬卧","软座","硬座","无座","其他"]
    51. self.table = QTableWidget()
    52. self.table.setColumnCount(15)
    53. self.table.setRowCount(0) #初始化为0行
    54. self.table.setHorizontalHeaderLabels(horizontalHeader)
    55. self.table.setEditTriggers(QTableWidget.NoEditTriggers) #不能编辑
    56. self.table.setSelectionBehavior(QTableWidget.SelectRows) #选中整行
    57. self.table.setSelectionMode(QTableWidget.SingleSelection)
    58. for index in range(self.table.columnCount()):
    59. headItem = self.table.horizontalHeaderItem(index)
    60. headItem.setFont(QFont("song", 12, QFont.Bold))
    61. headItem.setForeground(QBrush(Qt.gray))
    62. headItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    63. #self.table.setFrameShape(QFrame.HLine)#设定样式
    64. #self.table.setShowGrid(False) #取消网格线
    65. #self.table.verticalHeader().setVisible(False) #隐藏垂直表头
    66. #row_count = self.table.rowCount()
    67. #self.table.setColumnWidth(0,200)
    68. mainLayout = QHBoxLayout()
    69. mainLayout.addWidget(self.table)
    70. layout = QVBoxLayout()
    71. layout.addLayout(controlsLayout)
    72. layout.addLayout(mainLayout)
    73. self.setLayout(layout)
    74. self.buttonOK.clicked.connect(self.showMessage)
    75. self.showMaximized()
    76. def closeEvent(self, event): #关闭时弹窗提示
    77. reply = QMessageBox.question(self, '警告', '查询记录不会被保存,\n确认退出?',QMessageBox.Yes,QMessageBox.No)
    78. if reply == QMessageBox.Yes:
    79. event.accept()
    80. else:
    81. event.ignore()
    82. def showMessage(self): #显示查询信息
    83. stations_fz = dict(map(lambda t:(t[1],t[0]), stations.items())) #反转字典
    84. from_s = self.Editlabel1.text() #获取文本框内容
    85. to_s = self.Editlabel2.text()
    86. if (from_s in stations.keys()) and (to_s in stations.keys()):
    87. f = stations[from_s] # 通过字典转化为车站对应的缩写字母
    88. t = stations[to_s] # 通过字典转化为车站对应的缩写字母
    89. date = self.Editlabel3.text()
    90. d = str(date)
    91. # print(d)
    92. # print('正在查询' + from_s + '至' + to_s + '的列车...')
    93. url = 'https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=' + d + '&leftTicketDTO.from_station=' + f + '&leftTicketDTO.to_station=' + t +'&purpose_codes=ADULT'
    94. # print(url)
    95. warnings.filterwarnings("ignore") # 这个网站是有安全警告的,这段代码可以忽略警告
    96. r = requests.get(url, verify=False)
    97. raw_trains = r.json()['data']['result'] # 获取车次信息
    98. # print(raw_trains)
    99. num = len(raw_trains) # 获取车次数目
    100. # print('共查询到%d个车次信息'%num)
    101. self.message.setText("共查询到%d个车次信息"%num)
    102. if raw_trains == []:
    103. QMessageBox.warning(self, "提示", "暂无所查询的车次信息!")
    104. i=0
    105. self.table.setRowCount(num)
    106. self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) #关闭水平滚动条
    107. for raw_train in raw_trains:
    108. # split分割之后得到的是一个列表
    109. data_list = raw_train.split("|")
    110. # print(data_list)
    111. tra_no = data_list[2] #train_no
    112. from_s_no = data_list[16] #from_station_no
    113. to_s_no = data_list[17] #to_station_no
    114. seat_type = data_list[35] #seat_types
    115. tra_date = d #train_date
    116. checi = data_list[3] # 车次
    117. cfd = stations_fz[data_list[6]] #出发地,通过字典转换
    118. mdd = stations_fz[data_list[7]] #目的地
    119. fctime = data_list[8] # 发车时间
    120. ddtime = data_list[9] # 到达时间
    121. lishi = data_list[10] # 历时
    122. shangwuzuo = data_list[32] or "--" # 商务座/特等座
    123. yidengzuo = data_list[31] or "--" # 一等座
    124. erdengzuo = data_list[30] or "--" # 二等座
    125. gjruanwo = data_list[21] or "--" # 高级软卧
    126. ruanwo = data_list[23] or "--" # 软卧
    127. dongwo = data_list[33] or "--" # 动卧
    128. yingwo = data_list[28] or "--" # 硬卧
    129. ruanzuo = data_list[24] or "--" # 软座
    130. yingzuo = data_list[29] or "--" # 硬座
    131. wuzuo = data_list[26] or "--" # 无座
    132. others = data_list[22] or "--" # 其他
    133. 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
    134. r1 = requests.get(price_url, verify=False)
    135. # print(price_url)
    136. raw_prices = r1.json()['data'] # 获取车次信息
    137. if 'A1' in raw_prices.keys(): #A1:硬座
    138. pr_yz = raw_prices['A1']
    139. else:
    140. pr_yz = ''
    141. if 'A2' in raw_prices.keys(): # A2:软座
    142. pr_rz = raw_prices['A2']
    143. else:
    144. pr_rz = ''
    145. if 'A3' in raw_prices.keys(): # A3:硬卧
    146. pr_yw = raw_prices['A3']
    147. else:
    148. pr_yw = ''
    149. if 'A4' in raw_prices.keys(): # A4:软卧
    150. pr_rw = raw_prices['A4']
    151. else:
    152. pr_rw = ''
    153. if 'A6' in raw_prices.keys(): # A6:高级软卧
    154. pr_gjrw = raw_prices['A6']
    155. else:
    156. pr_gjrw = ''
    157. if 'A9' in raw_prices.keys(): # A9:商务座,特等座
    158. pr_swz = raw_prices['A9']
    159. else:
    160. pr_swz = ''
    161. if 'WZ' in raw_prices.keys(): # WZ:无座
    162. pr_wz = raw_prices['WZ']
    163. else:
    164. pr_wz = ''
    165. if 'M' in raw_prices.keys(): # M:一等座
    166. pr_ydz = raw_prices['M']
    167. else:
    168. pr_ydz = ''
    169. if 'O' in raw_prices.keys(): # O:二等座
    170. pr_edz = raw_prices['O']
    171. else:
    172. pr_edz = ''
    173. if 'F' in raw_prices.keys(): # F:动卧
    174. pr_dw = raw_prices['F']
    175. else:
    176. pr_dw = ''
    177. # print(pr_yz,pr_rz,pr_yw,pr_rw,pr_gjrw,pr_swz,pr_wz,pr_ydz,pr_edz,pr_dw)
    178. NewItem=QTableWidgetItem(checi)
    179. NewItem.setForeground(QColor(Qt.red))
    180. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter) #垂直居中
    181. self.table.setItem(i,0,NewItem)
    182. NewItem=QTableWidgetItem(cfd +'\n-\n'+mdd)
    183. NewItem.setFont(QFont("song", 9, QFont.Bold))
    184. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    185. self.table.setItem(i,1,NewItem)
    186. NewItem=QTableWidgetItem(fctime+'\n-\n'+ddtime)
    187. NewItem.setFont(QFont("song", 9, QFont.Bold))
    188. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    189. self.table.setItem(i,2,NewItem)
    190. NewItem=QTableWidgetItem(lishi)
    191. NewItem.setFont(QFont("song", 9, QFont.Bold))
    192. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    193. self.table.setItem(i,3,NewItem)
    194. NewItem=QTableWidgetItem(shangwuzuo+'\n'+ pr_swz)
    195. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    196. self.table.setItem(i,4,NewItem)
    197. NewItem=QTableWidgetItem(yidengzuo+'\n'+ pr_ydz)
    198. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    199. self.table.setItem(i,5,NewItem)
    200. NewItem=QTableWidgetItem(erdengzuo+'\n'+ pr_edz)
    201. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    202. self.table.setItem(i,6,NewItem)
    203. NewItem=QTableWidgetItem(gjruanwo+'\n'+ pr_gjrw)
    204. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    205. self.table.setItem(i,7,NewItem)
    206. NewItem=QTableWidgetItem(ruanwo+'\n'+ pr_rw)
    207. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    208. self.table.setItem(i,8,NewItem)
    209. NewItem=QTableWidgetItem(dongwo+'\n'+ pr_dw)
    210. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    211. self.table.setItem(i,9,NewItem)
    212. NewItem=QTableWidgetItem(yingwo+'\n'+ pr_yw)
    213. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    214. self.table.setItem(i,10,NewItem)
    215. NewItem=QTableWidgetItem(ruanzuo+'\n'+ pr_rz)
    216. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    217. self.table.setItem(i,11,NewItem)
    218. NewItem=QTableWidgetItem(yingzuo+'\n'+ pr_yz)
    219. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    220. self.table.setItem(i,12,NewItem)
    221. NewItem=QTableWidgetItem(wuzuo+'\n'+ pr_wz)
    222. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    223. self.table.setItem(i,13,NewItem)
    224. NewItem=QTableWidgetItem(others+'\n'+'')
    225. NewItem.setTextAlignment(Qt.AlignCenter | Qt.AlignVCenter)
    226. self.table.setItem(i,14,NewItem)
    227. self.table.setRowHeight(i, 60) #设置行高
    228. i=i+1
    229. #self.table.setSpan(0, 8, 2, 1) #合并单元格
    230. else:
    231. if from_s not in stations.keys():
    232. # print('请输入正确的出发地')
    233. QMessageBox.warning(self,"提示","请输入正确的出发地!")
    234. if to_s not in stations.keys():
    235. # print('请输入正确的目的地')
    236. QMessageBox.warning(self,"提示","请输入正确的目的地!")
    237. if __name__ == '__main__':
    238. app = QApplication(sys.argv)
    239. table = TableSheet()
    240. table.show()
    241. 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 |已有文章汇总 | 持续更新,直接看这篇就够了

    (更多内容+源码都在文章汇总哦!!欢迎阅读~)

  • 相关阅读:
    数据库基础入门 — SQL
    北邮22级信通院数电:Verilog-FPGA(10)第十周实验 实现移位寄存器74LS595(仿真方法验证)
    单元测试Mockito笔记
    什么是jsp?与servlet区别?request responds cookies session 整理与使用?controller与servlet的区别?
    UE4 回合游戏项目 20- 添加人物被攻击的动画
    外贸网站流量下降可能是这五点原因造成的
    组播分片报文重组后丢包问题
    CVPR2023 即插即用 SCConv (附代码)
    【原创】生成文件MD5图像,类似于GitHub的像素风格头像
    2022护网行动在即,关于护网的那些事儿
  • 原文地址:https://blog.csdn.net/weixin_55822277/article/details/125954812