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脚本设置系统时间的两种方法
Feb 21 Python
Python自定义线程类简单示例
Mar 23 Python
python框架中flask知识点总结
Aug 17 Python
python utc datetime转换为时间戳的方法
Jan 15 Python
使用 Python 处理 JSON 格式的数据
Jul 22 Python
python禁用键鼠与提权代码实例
Aug 16 Python
python GUI库图形界面开发之PyQt5布局控件QHBoxLayout详细使用方法与实例
Mar 06 Python
django处理select下拉表单实例(从model到前端到post到form)
Mar 13 Python
python查看矩阵的行列号以及维数方式
May 22 Python
详解Pycharm安装及Django安装配置指南
Sep 15 Python
Django vue前后端分离整合过程解析
Nov 20 Python
python基于pexpect库自动获取日志信息
Feb 01 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
谈一谈收音机的高放电路
2021/03/02 无线电
浅析PHP的ASCII码转换类
2013/07/05 PHP
php 批量替换html标签的实例代码
2013/11/26 PHP
PHP资源管理框架Assetic简介
2014/06/12 PHP
PHP中定义数组常量(array常量)的方法
2014/11/17 PHP
PHP GD库生成图像的几个函数总结
2014/11/19 PHP
ThinkPHP 3.2 版本升级了哪些内容
2015/03/05 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
js的写法基础分析
2011/01/17 Javascript
JavaScript中的函数模式详解
2015/02/11 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
2015/03/24 Javascript
如何通过js实现图片预览功能【附实例代码】
2016/03/30 Javascript
JavaScript队列、优先队列与循环队列
2016/11/14 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
2020/11/30 Javascript
JS实现搜索框文字可删除功能
2016/12/28 Javascript
使用snowfall.jquery.js实现爱心满屏飞的效果
2017/01/05 Javascript
使用contextMenu插件实现Bootstrap table弹出右键菜单
2017/02/20 Javascript
ES6学习之变量的两种命名方法示例
2017/07/18 Javascript
详解通过源码解析Node.js中cluster模块的主要功能实现
2018/05/16 Javascript
vue中使用百度脑图kityminder-core二次开发的实现
2019/09/26 Javascript
vue 实现通过vuex 存储值 在不同界面使用
2019/11/11 Javascript
Vue 打包的静态文件不能直接运行的原因及解决办法
2020/11/19 Vue.js
python数据结构树和二叉树简介
2014/04/29 Python
web.py在模板中输出美元符号的方法
2014/08/26 Python
跟老齐学Python之眼花缭乱的运算符
2014/09/14 Python
Python基于回溯法子集树模板解决全排列问题示例
2017/09/07 Python
Python flask框架实现查询数据库并显示数据
2020/06/04 Python
如何解决安装python3.6.1失败
2020/07/01 Python
Python基于pyjnius库实现访问java类
2020/07/31 Python
css3中flex布局宽度不生效的解决
2020/12/09 HTML / CSS
GUESS德国官网:美国牛仔服装品牌
2017/02/14 全球购物
美国球鞋寄卖网站:Stadium Goods
2018/05/09 全球购物
英国亚马逊官方网站:Amazon.co.uk
2019/08/09 全球购物
外贸采购员求职的自我评价
2013/11/26 职场文书
党员进社区活动总结
2015/05/07 职场文书
Python list列表删除元素的4种方法
2021/11/01 Python