def query_time_click(self): station = self.lineEdit_station.text() # 获取需要查询的起售车站 stations_time = eval(read('time.text')) # 读取所有车站与起售时间并转换为dic类型 stations = eval(read('stations.text')) # 读取所有车站并转换为dic类型 if station in stations_time: # 判断要搜索的站名是否存在 name_lit, time_list = query_time( station, stations.get(station)) # 查询起售车站对应的站名与起售时间 if len(name_lit) > 0: if self.gridLayout.count() != 0: # 每次点循环删除管理器的控件 while self.gridLayout.count(): # 获取第一个控件 item = self.gridLayout.takeAt(0) # 删除控件 widget = item.widget() widget.deleteLater() # 行数标记 i = -1 for n in range(len(name_lit)): # x 确定每行显示的个数 0,1,2,3 每行4个 x = n % 4 # 当x为0的时候设置换行 行数+1 if x == 0: i += 1 # 创建布局 self.widget = QtWidgets.QWidget() # 给布局命名 self.widget.setObjectName("widget" + str(n)) # 设置布局样式 self.widget.setStyleSheet( 'QWidget#' + "widget" + str(n) + "{border:2px solid rgb(175, 175, 175);background-color: rgb(255, 255, 255);}" ) # 创建个Qlabel控件用于显示图片 设置控件在QWidget中 self.label = QtWidgets.QLabel(self.widget) self.label.setAlignment(QtCore.Qt.AlignCenter) # 设置大小 self.label.setGeometry(QtCore.QRect(10, 10, 210, 65)) font = QtGui.QFont() # 创建字体对象 font.setPointSize(11) # 设置字体大小 font.setBold(True) # 开启粗体属性 font.setWeight(75) # 设置文字粗细 self.label.setFont(font) # 设置字体 self.label.setText(name_lit[n] + ' ' + time_list[n]) # 设置显示站名与起售时间 # 把动态创建的widegt布局添加到gridLayout中 i,x分别代表:行数以及每行的个数 self.gridLayout.addWidget(self.widget, i, x) # 设置高度为动态高度根据行数确定高度 每行300 self.scrollAreaWidgetContents.setMinimumHeight((i + 1) * 100) # 设置网格布局控件动态高度 self.gridLayoutWidget.setGeometry( QtCore.QRect(0, 0, 950, ((i + 1) * 100))) else: messageDialog('警告', '起售车站中没有该车站名称!') else: messageDialog('警告', '起售车站中没有该车站名称!')
def query(date, from_station, to_station): data.clear() # 查询请求地址 url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date=2020-07-31&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=BJP&purpose_codes=ADULT'.format( date, from_station, to_station) # 发送查询请求 response = requests.get(url) # 将json数据转换为字典类型,通过键值对取数据 result = response.json() result = result['data']['result'] # 判断车站文件是否存在 if isStations() == True: stations = eval(read()) # 读取所有车站文件并转换为dict类型 if len(result) != 0: for i in result: tmp_list = i.split('|') from_station = list(stations.key())[list( stations.values()).index(tmp_list[6])] to_station = list(stations.key())[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 query(date, from_station, to_station): data.clear() # 清空数据 stations = eval(read()) # 读取所有车站并转换为dic类型 place_of_departure = stations[from_station] # 在所有车站文件中找到对应的参数,出发地 destination = stations[to_station] # 目的地 # 查询请求地址 url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.' \ 'train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.' \ 'to_station={}&purpose_codes=ADULT'.format( date, place_of_departure, destination) # 发送查询请求 response = requests.get(url) response.encoding = "utf8" print(response.text) # # 将json数据转换为字典类型,通过键值对取数据 result = json.load(response.text) print(111111111111111) 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 query_price_click(self): get_from = self.textEdit_from.toPlainText() # 获取出发地 get_to = self.textEdit_to.toPlainText() # 获取到达地 get_price_date = self.textEdit_date.toPlainText() # 获取出发时间 global price_data # 判断车站文件是否存在 if is_stations('stations.text') == True: stations = eval(read('stations.text')) # 读取所有车站并转换为dic类型 # 判断所有参数是否为空,出发地、目的地、出发日期 if get_from != "" and get_to != "" and get_price_date != "": # 判断输入的车站名称是否存在,以及时间格式是否正确 if get_from in stations and get_to in stations and self.is_valid_date( get_price_date): # 计算时间差 time_difference = self.time_difference( self.get_time(), get_price_date).days # 判断时间差为0时证明是查询当前的查票, # 以及29天以后的车票。12306官方要求只能查询30天以内的车票 if time_difference >= 0 and time_difference <= 29: from_station = stations[ get_from] # 在所有车站文件中找到对应的参数,出发地 to_station = stations[get_to] # 目的地 price_data = query_price(get_price_date, from_station, to_station) # 发送查询请求,并获取返回的信息 train_price_remark = [ '车次', '始发站', '终点站', '出发时间', '到达时间', '历时', '商务座', '特等座', '一等座', '二等座', '高级软卧', '软卧', '硬卧', '动卧', '软座', '硬座', '无座', '其他', '备注' ] price_data.insert(0, train_price_remark) for k in price_data: size = len(k) if len(price_data) != 0: # 判断返回的数据是否为空 # 如果不是空的数据就将车票信息显示在表格中 self.displayPriceTable(len(price_data), size, price_data) else: messageDialog('警告', '没有返回的网络数据!') else: messageDialog( '警告', '超出查询日期的范围内,' '不可查询昨天的车票信息,以及29天以后的车票信息!') else: messageDialog('警告', '输入的站名不存在,或日期格式不正确!') else: messageDialog('警告', '请填写车站名称!') else: messageDialog('警告', '未下载车站查询文件!')
def on_click(self): get_from = self.textEdit.toPlainText() # 获取出发地 get_to = self.textEdit_2.toPlainText() # 获取到达地 get_date = self.textEdit_3.toPlainText() # 获取出发时间 # 判断车站文件是否存在 if is_stations('stations.text') == True: stations = eval(read('stations.text')) # 读取所有车站并转换为dic类型 # 判断所有参数是否为空,出发地、目的地、出发日期 if get_from != "" and get_to != "" and get_date != "": # 判断输入的车站名称是否存在,以及时间格式是否正确 if get_from in stations and get_to in stations and self.is_valid_date( get_date): # 计算时间差 time_difference = self.time_difference( self.get_time(), get_date).days # 判断时间差为0时证明是查询当前的查票, # 以及29天以后的车票。12306官方要求只能查询30天以内的车票 if time_difference >= 0 and time_difference <= 29: 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: messageDialog('警告', '没有返回的网络数据!') else: messageDialog( '警告', '超出查询日期的范围内,' '不可查询昨天的车票信息,以及29天以后的车票信息!') else: messageDialog('警告', '输入的站名不存在,或日期格式不正确!') else: messageDialog('警告', '请填写车站名称!') else: messageDialog('警告', '未下载车站查询文件!')
def query_ticketing_analysis_click(self): self.info_table = [] # 保存窗体表格中的车次信息 today_car_list.clear() # 清空今天列车信息,已处理是否有票 three_car_list.clear() # 清空三天列车信息,已处理是否有票 five_car_list.clear() # 清空五天列车信息,已处理是否有票 today_list.clear() # 清空今天列车信息,未处理是否有票 three_list.clear() # 清空三天列车信息,未处理是否有票 five_list.clear() # 清空五天列车信息,未处理是否有票 get_from = self.textEdit_analysis_from.toPlainText() # 获取出发地 get_to = self.textEdit_analysis_to.toPlainText() # 获取到达地 stations = eval(read('stations.text')) # 读取所有车站并转换为dic类型 # 判断所有参数是否为空,出发地、目的地 if get_from != "" and get_to != "": # 判断输入的车站名称是否存在,以及时间格式是否正确 if get_from in stations and get_to in stations: from_station = stations[get_from] # 在所有车站文件中找到对应的参数,出发地 to_station = stations[get_to] # 目的地 today = datetime.datetime.now() # 获取今天日期 three_set = datetime.timedelta(days=+2) # 三天内偏移天数 five_set = datetime.timedelta(days=+4) # 五天内偏移天数 three_day = (today + three_set).strftime( '%Y-%m-%d') # 三天格式化后的日期 five_day = (today + five_set).strftime('%Y-%m-%d') # 五天格式化后的日期 today = today.strftime('%Y-%m-%d') # 今天格式化后的日期 # 发送查询今天卧铺票信息的网络请求,并获取返回的信息 query_ticketing_analysis(today, from_station, to_station, 1) # 发送查询三天内卧铺票信息的网络请求,并获取返回的信息 query_ticketing_analysis(three_day, from_station, to_station, 3) # 发送查询五天内卧铺票信息的网络请求,并获取返回的信息 query_ticketing_analysis(five_day, from_station, to_station, 5) info_set = set() # 创建筛选车次集合,将相同车次进行整合,查看共有几趟列车 for i in today_car_list + three_car_list + five_car_list: # 因为在集合中必须是字符串才能进行整合,所以将车次信息转换为字符串类型,方便车次整合 info_set.add(str(i[0:6])) for info in info_set: # 遍历车次信息 info = eval(info) # 将车次信息再次转换成列表 is_today_ture = False # 判断今天是否存在某趟列车的标记 for i in today_car_list: # 遍历今天的车次信息,该车次信息是没有筛选的信息 if info[0] in i: # 判断整合后的车次,在今天的车次信息中是否存在 is_today_ture = True # 存在就进行标记 info.append( i[6]) # 如果存在就将,车次信息中是否有卧铺的信息添加至整合后的车次信息中 break # 跳出循环 if is_today_ture == False: # 如果今天没有某一趟列车就标记为'--' info.append('--') is_three_ture = False # 判断三天是否存在某趟列车的标记 for i in three_car_list: # 遍历三天的车次信息,该车次信息是没有筛选的信息 if info[0] in i: # 判断整合后的车次,在三天的车次信息中是否存在 is_three_ture = True # 存在就进行标记 info.append( i[6]) # 如果存在就将,车次信息中是否有卧铺的信息添加至整合后的车次信息中 break # 跳出循环 if is_three_ture == False: # 如果三天没有某一趟列车就标记为'--' info.append('--') is_five_ture = False # 判断五天是否存在某趟列车的标记 for i in five_car_list: # 遍历五天的车次信息,该车次信息是没有筛选的信息 if info[0] in i: # 判断整合后的车次,在五天的车次信息中是否存在 is_five_ture = True # 存在就进行标记 info.append( i[6]) # 如果存在就将,车次信息中是否有卧铺的信息添加至整合后的车次信息中 break # 跳出循环 if is_five_ture == False: # 如果五天没有某一趟列车就标记为'--' info.append('--') self.info_table.append(info) # 将最后结果添加至窗体表格的列表中 self.tableWidget.setRowCount(len(self.info_table)) # 设置表格行数 self.tableWidget.setColumnCount(9) # 设置表格列数 # 设置表格内容文字大小 font = QtGui.QFont() font.setPointSize(12) self.tableWidget.setFont(font) # 根据窗体大小拉伸表格 self.tableWidget.horizontalHeader().setSectionResizeMode( QtWidgets.QHeaderView.Stretch) # 循环遍历最终的信息 for row in range(len(self.info_table)): fraction = 0 # 分数,根据该分数判断列车的紧张程度 for column in range(9): if column == 6: # 如果是某趟列车今天是无票 if self.info_table[row][ column] == '无' or self.info_table[row][ column] == '--': fraction += 3 # 计3分 if column == 7: # 如果是某趟列车三天内是无票 if self.info_table[row][ column] == '无' or self.info_table[row][ column] == '--': fraction += 2 # 计2分 if column == 8: # 如果是某趟列车五天内是无票 if self.info_table[row][ column] == '无' or self.info_table[row][ column] == '--': fraction += 1 # 计1分 # 判断分数大于等于5分的车次为红色,说明该车次卧铺非常紧张 if fraction >= 5: # 定位是哪趟车次符合该条件,遍历该车次信息 for i in range(len(self.info_table[row])): # 表格列中的信息 item = QtWidgets.QTableWidgetItem( self.info_table[row][i]) item.setBackground(QColor(255, 0, 0)) # 设置该车次背景颜色 self.tableWidget.setItem(row, i, item) # 设置表格显示的内容 # 判断分数大于1与分数小于等于4的车次为橙色,说明该车次卧铺紧张 if fraction >= 1 and fraction <= 4: for i in range(len(self.info_table[row])): item = QtWidgets.QTableWidgetItem( self.info_table[row][i]) item.setBackground(QColor(255, 170, 0)) self.tableWidget.setItem(row, i, item) # 设置表格显示的内容 # 判断分数等于0的车次为绿色,说明该车次卧铺不紧张 if fraction == 0: for i in range(len(self.info_table[row])): item = QtWidgets.QTableWidgetItem( self.info_table[row][i]) item.setBackground(QColor(85, 170, 0)) self.tableWidget.setItem(row, i, item) # 设置表格显示的内容 self.show_broken_line() # 显示折线图 else: messageDialog('警告', '请填写车站名称!')