PyQt5爬取12306车票信息程序的实现


Posted in Python onMay 14, 2021

1、搭载QT环境

按win+R输入 pip install pyqt5 下载QT5 当然也可以去Qt的官网的下载 ,使用命令行更快捷方便 所以建议使用命令行 ,去官网下载安装有它的好处就是不用自己安装 toosl
作者使用的是pyCharm 完成后期的后台程序设置,使用pyCharm 外部工具链接把Designer,pyUIC,qrcTopy程序加进去

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

2、主窗体设置

打Qt5主程序设置主窗体,设计完成保存为windows
添加到创建好的python项目中,然后选中单击右键-》External toosl-》Py UIC 将ui文件转换成py文件
windows.py

from PyQt5.QtGui import QPalette, QPixmap, QColor


# result = []  # 保存车次分类后最后的数据


# UI类
class Ui_MainWindow(object):

    # 设置UI的方法
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")  # 设置窗体对象名称
        MainWindow.resize(960, 786)  # 设置窗体大小
        MainWindow.setMinimumSize(QtCore.QSize(960, 786))  # 主窗体最小值
        MainWindow.setMaximumSize(QtCore.QSize(960, 786))  # 主窗体最大值
        self.centralwidget = QtWidgets.QWidget(MainWindow)  # 主窗体的widget控件
        self.centralwidget.setObjectName("centralwidget")  # 设置对象名称

        # 通过label控件显示顶部图片
        self.label_title_img = QtWidgets.QLabel(self.centralwidget)
        self.label_title_img.setGeometry(QtCore.QRect(0, 0, 960, 141))
        self.label_title_img.setObjectName("label_title_img")
        title_img = QPixmap('img/TE3.png')  # 打开顶部位图
        self.label_title_img.setPixmap(title_img)  # 设置调色板

        # 查询部分的widget
        self.widget_query = QtWidgets.QWidget(self.centralwidget)
        self.widget_query.setGeometry(QtCore.QRect(0, 141, 960, 80))
        self.widget_query.setObjectName("widget_query")
        # 开启自动填充背景
        self.widget_query.setAutoFillBackground(True)
        palette = QPalette()  # 调色板类
        palette.setBrush(QPalette.Background, QtGui.QBrush(QtGui.QPixmap('img/bg2.png')))  # 设置背景图片
        self.widget_query.setPalette(palette)  # 为控件设置对应的调色板即可

        # 出发地与对应的编辑框控件
        self.label = QtWidgets.QLabel(self.widget_query)
        self.label.setGeometry(QtCore.QRect(30, 30, 54, 12))
        self.label.setObjectName("label")
        self.textEdit = QtWidgets.QTextEdit(self.widget_query)
        self.textEdit.setGeometry(QtCore.QRect(80, 20, 104, 31))
        font = QtGui.QFont()  # 创建QFont()对象
        font.setPointSize(13)  # 设置编辑框字体大小的值
        self.textEdit.setFont(font)  # 设置编辑框字体
        self.textEdit.setObjectName("textEdit")  # 出发地对应编辑框对象名称

        # 目的地与对应的编辑框
        self.label_2 = QtWidgets.QLabel(self.widget_query)
        self.label_2.setGeometry(QtCore.QRect(220, 30, 54, 12))
        self.label_2.setObjectName("label_2")
        self.textEdit_2 = QtWidgets.QTextEdit(self.widget_query)
        self.textEdit_2.setGeometry(QtCore.QRect(270, 20, 104, 31))
        font = QtGui.QFont()
        font.setPointSize(13)
        self.textEdit_2.setFont(font)
        self.textEdit_2.setObjectName("textEdit_2")

        # 出发日与有对应的编辑框
        self.label_3 = QtWidgets.QLabel(self.widget_query)
        self.label_3.setGeometry(QtCore.QRect(410, 30, 54, 12))
        self.label_3.setObjectName("label_3")
        self.textEdit_3 = QtWidgets.QTextEdit(self.widget_query)
        self.textEdit_3.setGeometry(QtCore.QRect(460, 20, 104, 31))
        font = QtGui.QFont()
        font.setPointSize(13)
        self.textEdit_3.setFont(font)
        self.textEdit_3.setObjectName("textEdit_3")
        # 查询按钮
        self.pushButton = QtWidgets.QPushButton(self.widget_query)
        self.pushButton.setGeometry(QtCore.QRect(610, 20, 91, 31))
        self.pushButton.setObjectName("pushButton")

        # 选择车次类型的widget
        self.widget_checkBox = QtWidgets.QWidget(self.centralwidget)
        self.widget_checkBox.setGeometry(QtCore.QRect(0, 220, 961, 35))
        self.widget_checkBox.setAutoFillBackground(False)
        self.widget_checkBox.setObjectName("widget_checkBox")
        # 开启自动填充背景
        self.widget_checkBox.setAutoFillBackground(True)
        palette = QPalette()  # 调色板类
        palette.setBrush(QPalette.Background, QtGui.QBrush(QtGui.QPixmap('img/bg3.png')))  # 设置背景图片
        self.widget_checkBox.setPalette(palette)  # 设置调色板控件对应的方法即可

        # 显示车次类型文字
        self.label_type = QtWidgets.QLabel(self.widget_checkBox)
        self.label_type.setGeometry(QtCore.QRect(30, 9, 65, 16))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.label_type.setFont(font)
        self.label_type.setObjectName("label_type")

        # 选择高铁
        self.checkBox_G = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_G.setGeometry(QtCore.QRect(100, 9, 70, 17))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.checkBox_G.setFont(font)
        self.checkBox_G.setObjectName("checkBox_GC")

        # 选择动车
        self.checkBox_D = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_D.setGeometry(QtCore.QRect(258, 9, 63, 17))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.checkBox_D.setFont(font)
        self.checkBox_D.setObjectName("checkBox_D")
        # 选择直达
        self.checkBox_Z = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_Z.setGeometry(QtCore.QRect(415, 9, 63, 17))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.checkBox_Z.setFont(font)
        self.checkBox_Z.setObjectName("checkBox_Z")
        # 选择特快
        self.checkBox_T = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_T.setGeometry(QtCore.QRect(572, 9, 63, 17))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.checkBox_T.setFont(font)
        self.checkBox_T.setObjectName("checkBox_T")
        # 选择快速
        self.checkBox_K = QtWidgets.QCheckBox(self.widget_checkBox)
        self.checkBox_K.setGeometry(QtCore.QRect(730, 9, 63, 17))
        font = QtGui.QFont()
        font.setPointSize(10)
        self.checkBox_K.setFont(font)
        self.checkBox_K.setObjectName("checkBox_K")

        # 通过label控件显示火车信息图片
        self.label_train_img = QtWidgets.QLabel(self.centralwidget)
        self.label_train_img.setGeometry(QtCore.QRect(0, 256, 960, 62))
        self.label_train_img.setObjectName("label_train_img")
        train_img = QPixmap('img/bg4.png')  # 打开火车信息位图
        self.label_train_img.setPixmap(train_img)  # 设置调色板
        # 显示车次信息的列表
        self.tableView = QtWidgets.QTableView(self.centralwidget)
        self.tableView.setGeometry(QtCore.QRect(0, 320, 960, 440))
        self.tableView.setObjectName("tableView")
        self.model = QStandardItemModel()# 创建存储数据的模式
        # 根据空间自动改变列宽度并且不可修改列宽度
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 设置表头不可见
        self.tableView.horizontalHeader().setVisible(False)
        # 纵向表头不可见
        self.tableView.verticalHeader().setVisible(False)
        # 设置表格内容文字大小
        font = QtGui.QFont()
        font.setPointSize(10)
        self.tableView.setFont(font)
        # 设置表格内容不可编辑
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 垂直滚动条始终开启
        self.tableView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # 主窗体设置主Widget
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)  # 调用retranslateUi方法显示窗体文字
        QtCore.QMetaObject.connectSlotsByName(MainWindow)  # 关联信号槽

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "爬票"))
        self.checkBox_T.setText(_translate("MainWindow", "T-特快"))
        self.checkBox_K.setText(_translate("MainWindow", "K-快速"))
        self.checkBox_Z.setText(_translate("MainWindow", "Z-直达"))
        self.checkBox_D.setText(_translate("MainWindow", "D-动车"))
        self.checkBox_G.setText(_translate("MainWindow", "GC-高铁"))
        self.label_type.setText(_translate("MainWindow", "车次类型:"))
        self.label.setText(_translate("MainWindow", "出发地:"))
        self.label_2.setText(_translate("MainWindow", "目的地:"))
        self.label_3.setText(_translate("MainWindow", "出发日:"))
        self.pushButton.setText(_translate("MainWindow", "查询"))
def show_MainWindow():
    app = QtWidgets.QApplication(sys.argv)  # 首先必须实例化QApplication类,作为GUI主程序入口
    MainWindow = QtWidgets.QMainWindow()  # 实例化QtWidgets.QMainWindow类,创建自带menu的窗体类型QMainWindow
    ui = Ui_MainWindow()  # 实例UI类
    ui.setupUi(MainWindow)  # 设置窗体UI
    MainWindow.show()  # 显示窗体
    sys.exit(app.exec_())  # 当来自操作系统的分发事件指派调用窗口时,
    # 应用程序开启主循环(mainloop)过程,
    # 当窗口创建完成,需要结束主循环过程,
    # 这时候呼叫sys.exit()方法来,结束主循环过程退出,
    # 并且释放内存。为什么用app.exec_()而不是app.exec()?
    # 因为exec是python系统默认关键字,为了以示区别,所以写成exec_


if __name__ == "__main__":
    if isStations() == False:  # 判断是否有所有车站的文件,没有就下载,有就直接显示窗体
        getStation()  # 下载所有车站文件
        show_MainWindow()  # 调用显示窗体的方法
    else:
        show_MainWindow()  # 调用显示窗体的方法

3、下载网站文件

在这之前我们的先去12306网站分析相关参数

PyQt5爬取12306车票信息程序的实现

获取完整的查票地址,注意每一个时期的地址是会发生改变的
创建用于下载网站文件的py文件,get_stations.py

import re
import  requests
import os

def getStation():
    # 发送请求获取所有车站名称,通过输入的站名称转化查询地址的参数
    url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9190'
    response = requests.get(url, verify=True)  # 请求并进行验证
    stations = re.findall(u'([\u4e00-\u9fa5]+)\|([A-Z]+)', response.text)  # 获取需要的车站名称
    stations = dict(stations)  # 转换为dic
    stations = str(stations)  # 转换为字符串类型否则无法写入文件
    write(stations)           #调用写入方法
def write(stations):
    file = open('stations.text', 'w', encoding='utf_8_sig')  # 以写模式打开文件
    file.write(stations)  # 写入数据
    file.close()
def read():
    file = open('stations.text', 'r', encoding='utf_8_sig')  # 以写模式打开文件
    data = file.readline()                                  #读取文件
    file.close()
    return data

def isStations():
    isStations = os.path.exists('stations.text')      #判断车站文件是否存在
    return isStations

4、车票信息的请求与显示

创建 query_request.py文件用于发现数据后的处理工作

from get_stations import *
import requests

'''5-7 目的地 3  车次 6  出发地 8  出发时间 9  到达时间 10 历时 26 无坐 29 硬座
   24 软座 28 硬卧 33 动卧 23 软卧 21 高级软卧 30 二等座 31 一等座 32 商务座特等座
'''
data = []  # 用于保存整理好的车次信息
type_data = []  # 保存车次分类后最后的数据
headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
           'Cookie':'_uab_collina=162044599452968647580256; JSESSIONID=ABB3D0F36AA12C3E5DAD5CD1D3CFF031; '
                    'RAIL_EXPIRATION=1620786883959; RAIL_DEVICEID=hu-C8-xxpDNSCuX_BiPS1CGOlxAyoXu-dncsv32QDPvmjG'
                    'R9Ua0AUywoyJ6FDeqRWMoixIIL24hbMf9ucn2MrHcPWjgYFJ6y6Fon9ihvKvZV8SIiGDYmZTuR-S2OLu3wyezmWPPO'
                    'un2B-v2BR_Q0wEYkIrBLIE8j; _jc_save_fromStation=%u5317%u4EAC%2CBJP; _jc_save_toStation=%u4E0'
                    'A%u6D77%2CSHH; _jc_save_fromDate=2021-05-08; _jc_save_toDate=2021-05-08; _jc_save_wfdc_flag='
                    'dc; BIGipServerpassport=988283146.50215.0000; route=495c805987d0f5c8c84b14f60212447d; BIGipS'
                    'erverotn=417857802.50210.0000; BIGipServerportal=3084124426.17183.0000'}
def query(date, from_station, to_station):
    data.clear()  # 清空数据
    type_data.clear()  # 清空车次分类保存的数据
    # 查询请求地址
    url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT'.format(
        date, from_station, to_station)
    # 发送查询请求
    response = requests.get(url=url,headers=headers)
    # # 将json数据转换为字典类型,通过键值对取数据
    result = response.json()
    result = result['data']['result']
    # 判断车站文件是否存在
    if isStations() == True:
        stations = eval(read())  # 读取所有车站并转换为dic类型
        if len(result) != 0:  # 判断返回数据是否为空
            for i in result:
                # # 分割数据并添加到列表中
                tmp_list = i.split('|')
                # 因为查询结果中出发站和到达站为站名的缩写字母,所以需要在车站库中找到对应的车站名称
                from_station = list(stations.keys())[list(stations.values()).index(tmp_list[6])]
                to_station = list(stations.keys())[list(stations.values()).index(tmp_list[7])]
                # 创建座位数组,由于返回的座位数据中含有空既“”,所以将空改成--这样好识别
                seat = [tmp_list[3], from_station, to_station, tmp_list[8], tmp_list[9], tmp_list[10]
                    , tmp_list[32], tmp_list[31], tmp_list[30], tmp_list[21]
                    , tmp_list[23], tmp_list[33], tmp_list[28], tmp_list[24], tmp_list[29], tmp_list[26]]
                newSeat = []
                # 循环将座位信息中的空既“”,改成--这样好识别
                for s in seat:
                    if s == "":
                        s = "--"
                    else:
                        s = s
                    newSeat.append(s)  # 保存新的座位信息
                data.append(newSeat)
        return data  # 返回整理好的车次信息


# 获取高铁信息的方法
def g_vehicle():
    if len(data) != 0:
        for g in data:  # 循环所有火车数据
            i = g[0].startswith('G')  # 判断车次首字母是不是高铁
            if i:  # 如果是将该条信息添加到高铁数据中
                type_data.append(g)


# 移除高铁信息的方法
def r_g_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for g in data:
            i = g[0].startswith('G')
            if i:  # 移除高铁信息
                type_data.remove(g)


# 获取动车信息的方法
def d_vehicle():
    if len(data) != 0:
        for d in data:  # 循环所有火车数据
            i = d[0].startswith('D')  # 判断车次首字母是不是动车
            if i == True:  # 如果是将该条信息添加到动车数据中
                type_data.append(d)


# 移除动车信息的方法
def r_d_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for d in data:
            i = d[0].startswith('D')
            if i == True:  # 移除动车信息
                type_data.remove(d)


# 获取直达车信息的方法
def z_vehicle():
    if len(data) != 0:
        for z in data:  # 循环所有火车数据
            i = z[0].startswith('Z')  # 判断车次首字母是不是直达
            if i == True:  # 如果是将该条信息添加到直达数据中
                type_data.append(z)


# 移除直达车信息的方法
def r_z_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for z in data:
            i = z[0].startswith('Z')
            if i == True:  # 移除直达车信息
                type_data.remove(z)


# 获取特快车信息的方法
def t_vehicle():
    if len(data) != 0:
        for t in data:  # 循环所有火车数据
            i = t[0].startswith('T')  # 判断车次首字母是不是特快
            if i == True:  # 如果是将该条信息添加到特快车数据中
                type_data.append(t)


# 移除特快车信息的方法
def r_t_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for t in data:
            i = t[0].startswith('T')
            if i == True:  # 移除特快车信息
                type_data.remove(t)


# 获取快速车数据的方法
def k_vehicle():
    if len(data) != 0:
        for k in data:  # 循环所有火车数据
            i = k[0].startswith('K')  # 判断车次首字母是不是快车
            if i == True:  # 如果是将该条信息添加到快车数据中
                type_data.append(k)


# 移除快速车数据的方法
def r_k_vehicle():
    if len(data) != 0 and len(type_data) != 0:
        for k in data:
            i = k[0].startswith('K')
            if i == True:  # 移除快车信息
                type_data.remove(k)

5、在主窗体中显示查票信息

注意这些方法是写在windows.py
(1)创建 get_time 和is_valid.date方法用判断日期是否有效

def get_time():
    # 获得当前时间时间戳
    now = int(time.time())
    # 转换为其它日期格式,如:"%Y-%m-%d %H:%M:%S"
    timeStruct = time.localtime(now)
    strTime = time.strftime("%Y-%m-%d", timeStruct)
    return strTime


def is_valid_date(str):
    '''判断是否是一个有效的日期字符串'''
    try:
        time.strptime(str, "%Y-%m-%d")
        return True
    except:
        return False

(2)创建车次分类复选事件处理方法

# 将所有车次分类复选框取消勾选
    def checkBox_default(self):
        self.checkBox_G.setChecked(False)
        self.checkBox_D.setChecked(False)
        self.checkBox_Z.setChecked(False)
        self.checkBox_T.setChecked(False)
        self.checkBox_K.setChecked(False)

    # 高铁复选框事件处理
    def change_G(self, state):
        # 选中将高铁信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取高铁信息
            g_vehicle()
            # 通过表格显示该车型数据
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_g_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 动车复选框事件处理
    def change_D(self, state):
        # 选中将动车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取动车信息
            d_vehicle()
            # 通过表格显示该车型数据
            self.displayTable(len(type_data), 16, type_data)

        else:
            # 取消选中状态将移除该数据
            r_d_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 直达复选框事件处理
    def change_Z(self, state):
        # 选中将直达车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取直达车信息
            z_vehicle()
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_z_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 特快复选框事件处理
    def change_T(self, state):
        # 选中将特快车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取特快车信息
            t_vehicle()
            self.displayTable(len(type_data), 16, type_data)
        else:
            # 取消选中状态将移除该数据
            r_t_vehicle()
            self.displayTable(len(type_data), 16, type_data)

    # 快速复选框事件处理
    def change_K(self, state):
        # 选中将快车信息添加到最后要显示的数据当中
        if state == QtCore.Qt.Checked:
            # 获取快速车信息
            k_vehicle()
            self.displayTable(len(type_data), 16, type_data)

        else:
            # 取消选中状态将移除该数据
            r_k_vehicle()
            self.displayTable(len(type_data), 16, type_data)

(3)创建messageDialog与displayTable方法分别用于非法输入的处理与车辆信息的显示

# 显示消息提示框,参数title为提示框标题文字,message为提示信息
    def messageDialog(self, title, message):
        msg_box = QMessageBox(QMessageBox.Warning, title, message)
        msg_box.exec_()

    # 显示车次信息的表格
    # train参数为共有多少趟列车,该参数作为表格的行。
    # info参数为每趟列车的具体信息,例如有座、无座卧铺等。该参数作为表格的列
    def displayTable(self, train, info, data):
        self.model.clear()
        for row in range(train):
            for column in range(info):
                # 添加表格内容
                item = QStandardItem(data[row][column])
                # 向表格存储模式中添加表格具体信息
                self.model.setItem(row, column, item)
        # 设置表格存储数据的模式
        self.tableView.setModel(self.model)

(4)创建on_click方法该方法用于查询事件的处理

# 查询按钮的单击事件
    def on_click(self):
        get_from = self.textEdit.toPlainText()  # 获取出发地
        get_to = self.textEdit_2.toPlainText()  # 获取到达地
        get_date = self.textEdit_3.toPlainText()  # 获取出发时间
        # 判断车站文件是否存在
        if isStations() == True:
            stations = eval(read())  # 读取所有车站并转换为dic类型
            # 判断所有参数是否为空,出发地、目的地、出发日期
            if get_from != "" and get_to != "" and get_date != "":
                # 判断输入的车站名称是否存在,以及时间格式是否正确
                if get_from in stations and get_to in stations and is_valid_date(get_date):
                    # 获取输入的日期是当前年初到现在一共过了多少天
                    inputYearDay = time.strptime(get_date, "%Y-%m-%d").tm_yday
                    # 获取系统当前日期是当前年初到现在一共过了多少天
                    yearToday = time.localtime(time.time()).tm_yday
                    # 计算时间差,也就是输入的日期减掉系统当前的日期
                    timeDifference = inputYearDay - yearToday
                    # 判断时间差为0时证明是查询当前的查票,
                    # 以及29天以后的车票。12306官方要求只能查询30天以内的车票
                    if timeDifference >= 0 and timeDifference <= 28:
                        from_station = stations[get_from]  # 在所有车站文件中找到对应的参数,出发地
                        to_station = stations[get_to]  # 目的地
                        data = query(get_date, from_station, to_station)  # 发送查询请求,并获取返回的信息
                        self.checkBox_default()
                        if len(data) != 0:  # 判断返回的数据是否为空
                            # 如果不是空的数据就将车票信息显示在表格中
                            self.displayTable(len(data), 16, data)
                        else:
                            self.messageDialog('警告', '没有返回的网络数据!')
                    else:
                        self.messageDialog('警告', '超出查询日期的范围内,'
                                                 '不可查询昨天的车票信息,以及29天以后的车票信息!')
                else:
                    self.messageDialog('警告', '输入的站名不存在,或日期格式不正确!')
            else:
                self.messageDialog('警告', '请填写车站名称!')
        else:
            self.messageDialog('警告', '未下载车站查询文件!')

(5)在retranslateUi方法中分别加入以下代码

self.textEdit_3.setText(get_time())  # 出发日显示当天日期
        self.pushButton.clicked.connect(self.on_click)  # 查询按钮指定单击事件的方法
        self.checkBox_G.stateChanged.connect(self.change_G)  # 高铁选中与取消事件
        self.checkBox_D.stateChanged.connect(self.change_D)  # 动车选中与取消事件
        self.checkBox_Z.stateChanged.connect(self.change_Z)  # 直达车选中与取消事件
        self.checkBox_T.stateChanged.connect(self.change_T)  # 特快车选中与取消事件
        self.checkBox_K.stateChanged.connect(self.change_K)  # 快车选中与取消事件

到此结束,以下是运行结果

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

PyQt5爬取12306车票信息程序的实现

到此这篇关于PyQt5爬取12306车票信息程序的实现的文章就介绍到这了,更多相关PyQt5爬取12306内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
复制粘贴功能的Python程序
Apr 04 Python
Python计算程序运行时间的方法
Dec 13 Python
Django进阶之CSRF的解决
Aug 01 Python
Python WEB应用部署的实现方法
Jan 02 Python
pyqt5实现登录界面的模板
May 30 Python
python基于socket进行端口转发实现后门隐藏的示例
Jul 25 Python
pytorch 共享参数的示例
Aug 17 Python
使用Python的turtle模块画国旗
Sep 24 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
Python 实现递归法解决迷宫问题的示例代码
Jan 12 Python
Python logging自定义字段输出及打印颜色
Nov 30 Python
selenium.webdriver中add_argument方法常用参数表
Apr 08 Python
python flask框架快速入门
如何将numpy二维数组中的np.nan值替换为指定的值
May 14 #Python
使用numpy nonzero 找出非0元素
May 14 #Python
Python机器学习之KNN近邻算法
May 14 #Python
Python爬虫基础讲解之请求
自己搭建resnet18网络并加载torchvision自带权重的操作
May 13 #Python
如何使用flask将模型部署为服务
May 13 #Python
You might like
PHP注释实例技巧
2008/10/03 PHP
php is_file()和is_dir()用于遍历目录时用法注意事项
2010/03/02 PHP
在项目中寻找代码的坏命名
2012/07/14 PHP
Thinkphp中的curd应用实用要点
2015/01/04 PHP
php获取linux命令结果的实例
2017/03/13 PHP
thinkPHP5.0框架应用请求生命周期分析
2017/03/25 PHP
js 目录列举函数
2008/11/06 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
2010/08/05 Javascript
javascript for循环从入门到偏门(效率优化+奇特用法)
2012/08/01 Javascript
js实现一个省市区三级联动选择框代码分享
2013/03/06 Javascript
js购物车实现思路及代码(个人感觉不错)
2013/12/23 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
AngularJS 入门教程之HTML DOM实例详解
2016/07/28 Javascript
BootStrap glyphicon图标无法显示的解决方法
2016/09/06 Javascript
jQuery图片前后对比插件beforeAfter用法示例【附demo源码下载】
2016/09/20 Javascript
JS实现探测网站链接的方法【测试可用】
2016/11/08 Javascript
ES6使用Set数据结构实现数组的交集、并集、差集功能示例
2017/10/31 Javascript
vue-cli3.X快速创建项目的方法步骤
2019/11/14 Javascript
JavaScript canvas绘制渐变颜色的矩形
2020/02/18 Javascript
es6数组之扩展运算符操作实例分析
2020/04/25 Javascript
微信小程序轮播图swiper代码详解
2020/12/01 Javascript
[49:56]VG vs Optic 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
使用Python更换外网IP的方法
2018/07/09 Python
pandas按行按列遍历Dataframe的几种方式
2019/10/23 Python
Python自动重新加载模块详解(autoreload module)
2020/04/01 Python
Booking.com德国:预订最好的酒店和住宿
2020/02/16 全球购物
大学生求职自荐信
2013/12/12 职场文书
手机促销活动方案
2014/02/05 职场文书
《会变的花树叶》教学反思
2014/02/10 职场文书
软件售后服务承诺书
2014/05/21 职场文书
小学生春游活动方案
2014/08/20 职场文书
计划生育证明书写要求
2014/09/17 职场文书
党员年终个人总结
2015/02/14 职场文书
村党组织公开承诺书
2015/04/30 职场文书
2016年教师节感言
2015/12/09 职场文书
分析设计模式之模板方法Java实现
2021/06/23 Java/Android