python第三方库PrettyTable使用实例,,一、简介Pretty
python第三方库PrettyTable使用实例,,一、简介Pretty
一、简介
PrettyTable 是python中的一个第三方库,可用来生成美观的ASCII格式的表格,十分实用。
二、安装
在保证能够通外网的情况下执行命令:pip install PrettyTable安装即可。
三、基本使用实例
import prettytable as pt#直接创建表tb = pt.PrettyTable()#表头字段tb.field_names = ["City name", "Area", "Population", "Annual Rainfall"]#按行添加数据tb.add_row(["Adelaide",1295, 1158259, 600.5])tb.add_row(["Brisbane",5905, 1857594, 1146.4])tb.add_row(["Darwin", 112, 120900, 1714.7])tb.add_row(["Hobart", 1357, 205556,619.5])print(tb)输出结果:+-----------+------+------------+-----------------+| City name | Area | Population | Annual Rainfall |+-----------+------+------------+-----------------+| Adelaide | 1295 | 1158259 | 600.5 || Brisbane | 5905 | 1857594 | 1146.4 || Darwin | 112 | 120900 | 1714.7 || Hobart | 1357 | 205556 | 619.5 |+-----------+------+------------+-----------------+
#按列添加数据tb.add_column(‘index‘,[1,2,3,4])print(tb)+-----------+------+------------+-----------------+-------+| City name | Area | Population | Annual Rainfall | index |+-----------+------+------------+-----------------+-------+| Adelaide | 1295 | 1158259 | 600.5 | 1 || Brisbane | 5905 | 1857594 | 1146.4 | 2 || Darwin | 112 | 120900 | 1714.7 | 3 || Hobart | 1357 | 205556 | 619.5 | 4 |+-----------+------+------------+-----------------+-------+#使用不同的输出风格tb.set_style(pt.MSWORD_FRIENDLY)print(‘--- style:MSWORD_FRIENDLY -----‘)print(tb)--- style:MSWORD_FRIENDLY -----| City name | Area | Population | Annual Rainfall || Adelaide | 1295 | 1158259 | 600.5 || Brisbane | 5905 | 1857594 | 1146.4 || Darwin | 112 | 120900 | 1714.7 || Hobart | 1357 | 205556 | 619.5 |tb.set_style(pt.PLAIN_COLUMNS)print(‘--- style:PLAIN_COLUMNS -----‘)print(tb)--- style:PLAIN_COLUMNS -----City name Area Population Annual Rainfall Adelaide 1295 1158259 600.5 Brisbane 5905 1857594 1146.4 Darwin 112 120900 1714.7 Hobart 1357 205556 619.5 #随机风格,每次不同tb.set_style(pt.RANDOM)print(‘--- style:MSWORD_FRIENDLY -----‘)print(tb)--- style:MSWORD_FRIENDLY -----@ Adelaide 1295 1158259 600.5 @@ Brisbane 5905 1857594 1146.4@@ Darwin 112 120900 1714.7@@ Hobart 1357 205556 619.5 @tb.set_style(pt.DEFAULT)print(‘--- style:DEFAULT -----‘)print(tb) --- style:DEFAULT -----+-----------+------+------------+-----------------+| City name | Area | Population | Annual Rainfall |+-----------+------+------------+-----------------+| Adelaide | 1295 | 1158259 | 600.5 || Brisbane | 5905 | 1857594 | 1146.4 || Darwin | 112 | 120900 | 1714.7 || Hobart | 1357 | 205556 | 619.5 |+-----------+------+------------+-----------------+#不打印,获取表格字符串s = tb.get_string()print(s)+-----------+------+------------+-----------------+| City name | Area | Population | Annual Rainfall |+-----------+------+------------+-----------------+| Adelaide | 1295 | 1158259 | 600.5 || Brisbane | 5905 | 1857594 | 1146.4 || Darwin | 112 | 120900 | 1714.7 || Hobart | 1357 | 205556 | 619.5 |+-----------+------+------------+-----------------+## 可以只获取指定列或行s = tb.get_string(fields=["City name", "Population"],start=1,end=4)print(s)+-----------+------------+| City name | Population |+-----------+------------+| Brisbane | 1857594 || Darwin | 120900 || Hobart | 205556 |+-----------+------------+# 自定义表格输出样式#设定左对齐tb.align = ‘l‘#设定数字输出格式tb.float_format = "2.2"#设定边框连接符为‘*"tb.junction_char = "*"#设定排序方式tb.sortby = "City name"#设定左侧不填充空白字符tb.left_padding_width = 0print(tb)*----------*-----*-----------*----------------*|City name |Area |Population |Annual Rainfall |*----------*-----*-----------*----------------*|Adelaide |1295 |1158259 |600.50 ||Brisbane |5905 |1857594 |1146.40 ||Darwin |112 |120900 |1714.70 ||Hobart |1357 |205556 |619.50 |*----------*-----*-----------*----------------*
#不显示边框tb.border = 0print(tb)City name Area Population Annual Rainfall Adelaide 1295 1158259 600.50 Brisbane 5905 1857594 1146.40 Darwin 112 120900 1714.70 Hobart 1357 205556 619.50 #修改边框分隔符tb.set_style(pt.DEFAULT)tb.horizontal_char = ‘+‘print(tb)+++++++++++++++++++++++++++++++++++++++++++++++++++| City name | Area | Population | Annual Rainfall |+++++++++++++++++++++++++++++++++++++++++++++++++++| Adelaide | 1295 | 1158259 | 600.50 || Brisbane | 5905 | 1857594 | 1146.40 || Darwin | 112 | 120900 | 1714.70 || Hobart | 1357 | 205556 | 619.50 |+++++++++++++++++++++++++++++++++++++++++++++++++++
#prettytable也支持输出HTML代码s = tb.get_html_string()print(s)<table> <tr> <th>City name</th> <th>Area</th> <th>Population</th> <th>Annual Rainfall</th> </tr> <tr> <td>Adelaide</td> <td>1295</td> <td>1158259</td> <td>600.50</td> </tr> <tr> <td>Brisbane</td> <td>5905</td> <td>1857594</td> <td>1146.40</td> </tr> <tr> <td>Darwin</td> <td>112</td> <td>120900</td> <td>1714.70</td> </tr> <tr> <td>Hobart</td> <td>1357</td> <td>205556</td> <td>619.50</td> </tr></table>#使用copy方法复制对象#tb.set_style(pt.DEFAULT)tb.horizontal_char = ‘.‘tb2 = tb.copy()tb.align = ‘l‘tb2.align = ‘r‘print(tb)print(tb2)+...........+......+............+.................+| City name | Area | Population | Annual Rainfall |+...........+......+............+.................+| Adelaide | 1295 | 1158259 | 600.50 || Brisbane | 5905 | 1857594 | 1146.40 || Darwin | 112 | 120900 | 1714.70 || Hobart | 1357 | 205556 | 619.50 |+...........+......+............+.................++...........+......+............+.................+| City name | Area | Population | Annual Rainfall |+...........+......+............+.................+| Adelaide | 1295 | 1158259 | 600.50 || Brisbane | 5905 | 1857594 | 1146.40 || Darwin | 112 | 120900 | 1714.70 || Hobart | 1357 | 205556 | 619.50 |+...........+......+............+.................+#直接赋值,得到的是索引tb.horizontal_char = ‘-‘tb.aliign = ‘l‘tb3 = tbtb3.align = ‘r‘print(tb)print(tb3)+-----------+------+------------+-----------------+| City name | Area | Population | Annual Rainfall |+-----------+------+------------+-----------------+| Adelaide | 1295 | 1158259 | 600.50 || Brisbane | 5905 | 1857594 | 1146.40 || Darwin | 112 | 120900 | 1714.70 || Hobart | 1357 | 205556 | 619.50 |+-----------+------+------------+-----------------++-----------+------+------------+-----------------+| City name | Area | Population | Annual Rainfall |+-----------+------+------------+-----------------+| Adelaide | 1295 | 1158259 | 600.50 || Brisbane | 5905 | 1857594 | 1146.40 || Darwin | 112 | 120900 | 1714.70 || Hobart | 1357 | 205556 | 619.50 |+-----------+------+------------+-----------------+
四、查询12306余票信息
首先我们来看看每查询一条信息12306网站返回的信息:
请求链接:
https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-01-31&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=GZG&purpose_codes=ADULT
很显然我们只需要关注三个参数:train_date,from_station,to_station。
#获得result
1 import requests 2 import urllib 3 import json 5 """获取data""" 6 def getData(url): 7 data = ‘‘ 8 while 1: 9 try:10 headers = {‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0‘}11 12 # 关键代码:###############################################13 14 req = urllib.request.Request(url=url, headers=headers)15 16 data = urllib.request.urlopen(req).read().decode(‘utf-8‘)17 18 ###########################################################19 if data.startswith(u‘\ufeff‘):20 data = data.encode(‘utf8‘)[3:].decode(‘utf-8‘)21 break22 except:23 continue24 return data25 26 """获取result"""27 28 def resolveData():29 #查询链接30 url = ‘https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-01-31&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=GZG&purpose_codes=ADULT‘31 32 #获取数据33 while 1:34 try:35 data = getData(url)36 lists = json.loads(data)["data"]["result"]37 break38 except:39 continue#获取失败则重新获取40 for item in lists:#打印result信息41 print(item)
调用resolveData():
观察这一长串字符我们还是能发现规律的,所有的信息都以"|"为分割线,图中已经显示了一些信息,其他信息需要我们观察多个result结果才能找出对应位置。
解析result信息:
1 """获取result""" 2 3 def resolveData(): 4 5 #查询链接 6 7 url = ‘https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-01-31&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=GZG&purpose_codes=ADULT‘ #获取数据 8 9 while 1: 10 11 try: 12 13 data = getData(url) 14 15 lists = json.loads(data)["data"]["result"] 16 17 break 18 19 except: 20 21 continue 22 23 cont = [] 24 25 name = [ 26 27 "station_train_code", 28 29 "from_station_name", 30 31 ‘start_time‘, 32 33 "lishi", 34 35 "swz_num", 36 37 "zy_num", 38 39 "ze_num", 40 41 "gr_num", 42 43 "rw_num", 44 45 "dw_num", 46 47 "yw_num", 48 49 "rz_num", 50 51 "yz_num", 52 53 "wz_num", 54 55 "qt_num", 56 57 "note_num" 58 59 ] 60 61 62 63 for items in lists:#遍历result的每一项 64 65 #data字典用于存放每一车次的余票信息 66 67 data = { 68 69 "station_train_code": ‘‘, 70 71 "from_station_name": ‘‘, 72 73 "to_station_name": ‘‘, 74 75 ‘start_time‘: ‘‘, 76 77 ‘end‘: ‘‘, 78 79 "lishi": ‘‘, 80 81 "swz_num": ‘‘, 82 83 "zy_num": ‘‘, 84 85 "ze_num": ‘‘, 86 87 "dw_num": ‘‘, 88 89 "gr_num": ‘‘, 90 91 "rw_num": ‘‘, 92 93 "yw_num": ‘‘, 94 95 "rz_num": ‘‘, 96 97 "yz_num": ‘‘, 98 99 "wz_num": ‘‘,100 101 "qt_num": ‘‘,102 103 "note_num": ‘‘104 105 }106 107 item = items.split(‘|‘)#用"|"进行分割108 109 data[‘station_train_code‘] = item[3]#车次在3号位置110 111 data[‘from_station_name‘] = item[6]#始发站信息在6号位置112 113 data[‘to_station_name‘] = item[7]#终点站信息在7号位置114 115 data[‘start_time‘] = item[8]#出发时间信息在8号位置116 117 data[‘arrive_time‘] = item[9]#抵达时间在9号位置118 119 data[‘lishi‘] = item[10]#经历时间在10号位置120 121 data[‘swz_num‘] = item[32] or item[25]# 特别注意:商务座在32或25位置122 123 data[‘zy_num‘] = item[31]#一等座信息在31号位置124 125 data[‘ze_num‘] = item[30]#二等座信息在30号位置126 127 data[‘gr_num‘] = item[21]#高级软卧信息在31号位置128 129 data[‘rw_num‘] = item[23]#软卧信息在23号位置130 131 data[‘dw_num‘] = item[27]#动卧信息在27号位置132 133 data[‘yw_num‘] = item[28]#硬卧信息在28号位置134 135 data[‘rz_num‘] = item[24]#软座信息在24号位置136 137 data[‘yz_num‘] = item[29]#硬座信息在29号位置138 139 data[‘wz_num‘] = item[26]#无座信息在26号位置140 141 data[‘qt_num‘] = item[22]#其他信息在22号位置142 143 data[‘note_num‘] = item[1]#备注在1号位置144 145 146 147 #如果没有信息则用“-”代替148 149 for pos in name:150 151 if data[pos] == ‘‘:152 153 data[pos] = ‘-‘154 155 156 157 cont.append(data)158 159 tickets = []#存放所有车次的余票信息160 161 #格式化添加进tickets中162 163 for x in cont:164 165 tmp = []166 167 for y in name:168 169 if y == "from_station_name":170 171 s = stations2CN[x[y]] + ‘--‘ + stations2CN[x["to_station_name"]]172 173 tmp.append(s)174 175 elif y == "start_time":176 177 s = x[y] + ‘--‘ + x["arrive_time"]178 179 tmp.append(s)180 181 elif y == "station_train_code":182 183 s = x[y]184 185 tmp.append(s)186 187 else:188 189 tmp.append(x[y])190 191 tickets.append(tmp)192 193 return tickets#返回所有车次余票信息194 195 196 197 if __name__ == "__main__":#main方法198 199 tickets = resolveData()200 201 for ticket in tickets:202 203 print(ticket)
同12306官网进行对比,查询解析准确。搞定!
下一步我们将使数据输出的更加漂亮。
1 #打印车票函数: 2 from prettytable import PrettyTable 3 #显示查询结果 4 def display(tickets): 5 ptable = PrettyTable(‘车次 出发/到达站 出发/到达时间 历时 商务座 一等座 二等座 高级软卧 软卧 动卧 硬卧 软座 硬座 无座 其他 备注‘.split(‘ ‘)) 6 for ticket in tickets: 7 ptable.add_row(ticket) 8 print(ptable) 9 10 if __name__ == "__main__":#main方法11 tickets = resolveData()12 display(tickets)13 input(‘按任意键退出...‘)
使用了prettytable后使输出十分规整,现在我想为这一表格中的字体加上颜色,我们需要使用colorama。
环境安装:pip install colorama
创建一个专门用于更改颜色的类Colored并且添加相应方法:
1 from colorama import init, Fore, Back, Style 2 3 init(autoreset=False) 4 class Colored(object): 5 # 前景色:红色 背景色:默认 6 def red(self, s): 7 return Fore.LIGHTRED_EX + s + Fore.RESET 8 # 前景色:绿色 背景色:默认 9 def green(self, s):10 return Fore.LIGHTGREEN_EX + s + Fore.RESET11 def yellow(self, s):12 return Fore.LIGHTYELLOW_EX + s + Fore.RESET13 def white(self,s):14 return Fore.LIGHTWHITE_EX + s + Fore.RESET15 def blue(self,s):16 return Fore.LIGHTBLUE_EX + s + Fore.RESET
现在我们使用这个类,修改resolveData()函数的部分代码:
def resolveData(): #查询链接 url = ‘https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-01-31&leftTicketDTO.from_station=XAY&leftTicketDTO.to_station=GZG&purpose_codes=ADULT‘ #获取数据 while 1: try: data = getData(url) lists = json.loads(data)["data"]["result"] break except: continue cont = [] name = [ "station_train_code", "from_station_name", ‘start_time‘, "lishi", "swz_num", "zy_num", "ze_num", "gr_num", "rw_num", "dw_num", "yw_num", "rz_num", "yz_num", "wz_num", "qt_num", "note_num" ] color = Colored()#创建Colored对象 for items in lists:#遍历result的每一项 #data字典用于存放每一车次的余票信息 data = { "station_train_code": ‘‘, "from_station_name": ‘‘, "to_station_name": ‘‘, ‘start_time‘: ‘‘, ‘end‘: ‘‘, "lishi": ‘‘, "swz_num": ‘‘, "zy_num": ‘‘, "ze_num": ‘‘, "dw_num": ‘‘, "gr_num": ‘‘, "rw_num": ‘‘, "yw_num": ‘‘, "rz_num": ‘‘, "yz_num": ‘‘, "wz_num": ‘‘, "qt_num": ‘‘, "note_num": ‘‘ } item = items.split(‘|‘)#用"|"进行分割 data[‘station_train_code‘] = item[3]#车次在3号位置 data[‘from_station_name‘] = item[6]#始发站信息在6号位置 data[‘to_station_name‘] = item[7]#终点站信息在7号位置 data[‘start_time‘] = item[8]#出发时间信息在8号位置 data[‘arrive_time‘] = item[9]#抵达时间在9号位置 data[‘lishi‘] = item[10]#经历时间在10号位置 data[‘swz_num‘] = item[32] or item[25]# 特别注意:商务座在32或25位置 data[‘zy_num‘] = item[31]#一等座信息在31号位置 data[‘ze_num‘] = item[30]#二等座信息在30号位置 data[‘gr_num‘] = item[21]#高级软卧信息在31号位置 data[‘rw_num‘] = item[23]#软卧信息在23号位置 data[‘dw_num‘] = item[27]#动卧信息在27号位置 data[‘yw_num‘] = item[28]#硬卧信息在28号位置 data[‘rz_num‘] = item[24]#软座信息在24号位置 data[‘yz_num‘] = item[29]#硬座信息在29号位置 data[‘wz_num‘] = item[26]#无座信息在26号位置 data[‘qt_num‘] = item[22]#其他信息在22号位置 if item[0] == ‘null‘: data[‘note_num‘] = item[1] else: data[‘note_num‘] = color.white(item[1])#加高亮白色 #如果没有信息则用“-”代替 for pos in name: if data[pos] == ‘‘: data[pos] = ‘-‘ cont.append(data) tickets = []#存放所有车次的余票信息 #格式化添加进tickets中 for x in cont: tmp = [] for y in name: if y == "from_station_name": s = color.green(stations2CN[x[y]]) + ‘\n‘ + color.red(stations2CN[x["to_station_name"]])#始发站绿色,终点站红色 tmp.append(s) elif y == "start_time": s = color.green(x[y]) + ‘\n‘ + color.red(x["arrive_time"]) tmp.append(s) elif y == "station_train_code": s = color.yellow(x[y]) tmp.append(s) else: tmp.append(x[y]) tickets.append(tmp) return tickets#返回所有车次余票信息
我们能实现很漂亮的输出了,可是只是固定时间固定车站之间的车票信息,在本次中我们使用docopt来实现命令行的参数输入,从而查询任意时间任意两个车站的余票。
环境安装:pip install docopt
使用docopt实现命令行的输入:
1 """Train tickets query via command-line. 2 Usage: 3 tickets <from> <to> <date> 4 5 Options: 6 -h,--help 显示帮助菜单 7 from 出发车站 8 to 终点站 9 date 出发日期10 11 Example:12 filename 南京 北京 2016-07-0113 """14 from docopt import docopt15 16 def cli():17 """command-line interface"""18 arguments = docopt(__doc__)
在main函数中调用cli()方法并打印arguments:
成功的通过命令行传递查询参数。
接下来我们只需要稍微修改一下resolveData函数就行了。
修改两行:
1 def resolveData(from_station,to_station,from_date):2 #查询链接3 url = ‘https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT‘.format(from_date, stations2CODE[from_station],stations2CODE[to_station]) #获取数据
stations2CODE将输入的车站名转换成12306规定的代码。这是一个字典,具体在stationInfo.py中。
在cli()函数中调用修改后的resolveData方法并打印表格:
1 def cli():2 """command-line interface"""3 arguments = docopt(__doc__)4 tickets = resolveData(arguments[‘<from>‘], arguments[‘<to>‘], arguments[‘<date>‘])5 display(tickets)
添加票价信息:
票价的查询根据前面result的解析是无法获取的,票价需要另外发送请求获取。
请求链接:
https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=88000K131008&from_station_no=12&to_station_no=27&seat_types=1413&train_date=2018-01-30
关注train_no、from_station_no、to_station_no、seat_types、train_date这几个参数。
有了前面教程解析车票信息result的基础解析车票也是大同小异罢了,找出对应车票类型对应的票价对应的位置就行。
实现获取车票票价的函数:
1 #pricesDic用于存放票价信息 2 pricesDic = { 3 ‘A‘: ‘‘, 4 ‘B‘: ‘‘, 5 ‘C‘: ‘‘, 6 ‘D‘: ‘‘, 7 ‘E‘: ‘‘, 8 ‘F‘: ‘‘, 9 ‘G‘: ‘‘,10 ‘H‘: ‘‘,11 ‘I‘: ‘‘,12 ‘J‘: ‘‘13 }14 15 def getPrice(threadname,train_no, from_station_no, to_station_no, seat_types, date,pricesDic):16 while 1:17 try:18 headers = {‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23.0) Gecko/20100101 Firefox/23.0‘}19 moneyUrl = "https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no={}&from_station_no={}&to_station_no={}&seat_types={}&train_date={}".format(20 train_no, from_station_no, to_station_no, seat_types, date)21 req = urllib.request.Request(url=moneyUrl, headers=headers)22 r_price = urllib.request.urlopen(req).read().decode(‘utf-8‘)23 if r_price.startswith(u‘\ufeff‘):24 r_price = r_price.encode(‘utf8‘)[3:].decode(‘utf-8‘)25 # print(r_price)26 r_price = json.loads(r_price)27 break28 except:29 continue30 price = r_price[‘data‘]31 price = dict(price)#获取data字典,票价信息在字典中32 A = (‘A9‘ in price.keys())#商务座票价对应key是A9或者P33 if A == False:34 A = (‘P‘ in price.keys())35 if A == False:36 A = ‘‘37 else:38 A = price[‘P‘]39 else:40 A = price[‘A9‘]41 42 B = (‘M‘ in price.keys())#一等座对应key为M43 if B == False:44 B = ‘‘45 else:46 B = price[‘M‘]47 C = (‘O‘ in price.keys())#二等座对应key为O48 if C == False:49 C = ‘‘50 else:51 C = price[‘O‘]52 D = (‘A6‘ in price.keys())53 if D == False:54 D = ‘‘55 else:56 D = price[‘A6‘]57 E = (‘A4‘ in price.keys())58 if E == False:59 E = ‘‘60 else:61 E = price[‘A4‘]62 F = (‘F‘ in price.keys())63 if F == False:64 F = ‘‘65 else:66 F = price[‘F‘]67 G = (‘A3‘ in price.keys())68 if G == False:69 G = ‘‘70 else:71 G = price[‘A3‘]72 73 H = (‘A2‘ in price.keys())74 if H == False:75 H = ‘‘76 else:77 H = price[‘A2‘]78 I = (‘A1‘ in price.keys())79 if I == False:80 I = ‘‘81 else:82 I = price[‘A1‘]83 84 J = (‘WZ‘ in price.keys())85 if J == False:86 J = ‘‘87 else:88 J = price[‘WZ‘]89 pricesDic[‘A‘] = A90 pricesDic[‘B‘] = B91 pricesDic[‘C‘] = C92 pricesDic[‘D‘] = D93 pricesDic[‘E‘] = E94 pricesDic[‘F‘] = F95 pricesDic[‘G‘] = G96 pricesDic[‘H‘] = H97 pricesDic[‘I‘] = I98 pricesDic[‘J‘] = J
我实现查询票价使用了Python中的线程,另外开启一个线程去查询票价:
1 import threading 2 3 threadLock = threading.Lock() 4 class myThread (threading.Thread): 5 def __init__(self, threadID, threadName, train_no, from_station_no, to_station_no, seat_types, date,pricesDic): 6 threading.Thread.__init__(self) 7 self.threadID = threadID 8 self.threadName = threadName 9 self.train_no = train_no10 self.from_station_no = from_station_no11 self.to_station_no = to_station_no12 self.seat_types = seat_types13 self.date = date14 self.pricesDic = pricesDic15 def run(self):16 #print ("开始线程:" + self.threadName)17 # 获取锁,用于线程同步18 threadLock.acquire()19 getPrice(self.threadName, self.train_no, self.from_station_no, self.to_station_no, self.seat_types, self.date, self.pricesDic)20 # 释放锁,开启下一个线程21 threadLock.release()22 #print ("退出线程:" + self.threadName)
在resolveData函数中开启线程查询票价,并且将票价加入余票信息中:
再次修改resolveData函数,观察变化:
1 def resolveData(from_station, to_station, date): 2 #拼接出查询链接 3 url = ‘https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date={}&leftTicketDTO.from_station={}&leftTicketDTO.to_station={}&purpose_codes=ADULT‘.format(date, stations2CODE[from_station], stations2CODE[to_station]) 4 #获取数据 5 while 1: 6 try: 7 data = getData(url) 8 lists = json.loads(data)["data"]["result"] 9 # if data[‘status‘] == False: 10 # print(‘获取失败!请检查网络‘) 11 # break 12 break 13 except: 14 continue 15 cont = [] 16 name = [ 17 "station_train_code", 18 "from_station_name", 19 ‘start_time‘, 20 "lishi", 21 "swz_num", 22 "zy_num", 23 "ze_num", 24 "gr_num", 25 "rw_num", 26 "dw_num", 27 "yw_num", 28 "rz_num", 29 "yz_num", 30 "wz_num", 31 "qt_num", 32 "note_num" 33 ] 34 color = Colored() 35 for items in lists: 36 data = { 37 "station_train_code": ‘‘, 38 "from_station_name": ‘‘, 39 "to_station_name": ‘‘, 40 ‘start_time‘: ‘‘, 41 ‘end‘: ‘‘, 42 "lishi": ‘‘, 43 "swz_num": ‘‘, 44 "zy_num": ‘‘, 45 "ze_num": ‘‘, 46 "dw_num": ‘‘, 47 "gr_num": ‘‘, 48 "rw_num": ‘‘, 49 "yw_num": ‘‘, 50 "rz_num": ‘‘, 51 "yz_num": ‘‘, 52 "wz_num": ‘‘, 53 "qt_num": ‘‘, 54 "note_num": ‘‘ 55 } 56 item = items.split(‘|‘) 57 data[‘station_train_code‘] = item[3] 58 data[‘from_station_name‘] = item[6] 59 data[‘to_station_name‘] = item[7] 60 data[‘start_time‘] = item[8] 61 data[‘arrive_time‘] = item[9] 62 data[‘lishi‘] = item[10] 63 data[‘swz_num‘] = item[32] or item[25]# 商务座在32或25位置 64 data[‘zy_num‘] = item[31] 65 data[‘ze_num‘] = item[30] 66 data[‘gr_num‘] = item[21] 67 data[‘rw_num‘] = item[23] 68 data[‘dw_num‘] = item[27] 69 data[‘yw_num‘] = item[28] 70 data[‘rz_num‘] = item[24] 71 data[‘yz_num‘] = item[29] 72 data[‘wz_num‘] = item[26] 73 data[‘qt_num‘] = item[22] 74 if item[0] == ‘null‘: 75 data[‘note_num‘] = item[1] 76 else: 77 data[‘note_num‘] = color.white(item[1]) 78 #解析出查询票价需要的参数 79 train_no = item[2] 80 from_station_no = item[16] 81 to_station_no = item[17] 82 types = item[35] 83 getPriceThread = myThread(1, "Thread-1", train_no, from_station_no, to_station_no, types, date, pricesDic) 84 getPriceThread.start()#开启查询车票的线程 85 for pos in name: 86 if data[pos] == ‘‘: 87 data[pos] = ‘-‘ 88 threadLock.acquire()#必须加锁,这是为了线程同步 89 for pos in priceName:#将票价添加进余票信息中 90 if pos == ‘swz_num‘: 91 data[‘swz_num‘] = data[‘swz_num‘] +‘\n‘+ color.blue(pricesDic[‘A‘]) 92 if pos == ‘zy_num‘: 93 data[‘zy_num‘] = data[‘zy_num‘] +‘\n‘+ color.blue(pricesDic[‘B‘]) 94 if pos == ‘ze_num‘: 95 data[‘ze_num‘] = data[‘ze_num‘] +‘\n‘+ color.blue(pricesDic[‘C‘]) 96 if pos == ‘gr_num‘: 97 data[‘gr_num‘] = data[‘gr_num‘] +‘\n‘+ color.blue(pricesDic[‘D‘]) 98 if pos == ‘rw_num‘: 99 data[‘rw_num‘] = data[‘rw_num‘] +‘\n‘+ color.blue(pricesDic[‘E‘])100 if pos == ‘dw_num‘:101 data[‘dw_num‘] = data[‘dw_num‘] +‘\n‘+ color.blue(pricesDic[‘F‘])102 if pos == ‘yw_num‘:103 data[‘yw_num‘] = data[‘yw_num‘] +‘\n‘+ color.blue(pricesDic[‘G‘])104 if pos == ‘rz_num‘:105 data[‘rz_num‘] = data[‘rz_num‘] +‘\n‘+ color.blue(pricesDic[‘H‘])106 if pos == ‘yz_num‘:107 data[‘yz_num‘] = data[‘yz_num‘] +‘\n‘+ color.blue(pricesDic[‘I‘])108 if pos == ‘wz_num‘:109 data[‘wz_num‘] = data[‘wz_num‘] +‘\n‘+ color.blue(pricesDic[‘J‘])110 threadLock.release()111 cont.append(data)112 color = Colored()113 tickets = []114 for x in cont:115 tmp = []116 for y in name:117 if y == "from_station_name":118 s = color.green(stations2CN[x[y]]) + ‘\n‘ + color.red(stations2CN[x["to_station_name"]])119 tmp.append(s)120 elif y == "start_time":121 s = color.green(x[y]) + ‘\n‘ + color.red(x["arrive_time"])122 tmp.append(s)123 elif y == "station_train_code":124 s = color.yellow(x[y])125 tmp.append(s)126 else:127 tmp.append(x[y])128 tickets.append(tmp)129 return tickets#返回所有车次余票信息
最终测试:
成功获取票价!
到这来为止我们就结束了DOS界面的开发。源代码:
链接:https://pan.baidu.com/s/1c1Gdxra 密码:6xpz
我在此基础上实现了连续多天的查询,并且实现了列车类型的过滤,
源代码在此:链接:https://pan.baidu.com/s/1jI2Ak4Y 密码:02gu
转载原文:https://blog.csdn.net/qq_25343557/article/details/78965044
python第三方库PrettyTable使用实例
相关内容
- python实现去重排序,,功能要求: 明
- 在python中对元祖进行排序,,在python里你可
- 关于python使用requests依赖包时出现版本不匹配的警告问
- 安装python、pycharm 和anaconda,, 由于刚开始学习p
- Python “图灵机器人”对话交互,,1、创建图灵机器人账
- Python3 tkinter基础 Entry get 点击按钮 将输入框中文字输出
- Python3安装Pyyaml,python3pyyaml,转自:http://
- python基础——4、python应用(文件操作,字典,列表,输
- Python 输入和输出,Python输入输出,一、在控制台上输入
- Python 的版本控制,Python版本控制,版本控制工具的差异
评论关闭