最近我看到看到使用python實(shí)現(xiàn)火車(chē)票查詢(xún),我自己也實(shí)現(xiàn)了,感覺(jué)收獲蠻多的,下面我就把每一步驟都詳細(xì)給分享出來(lái)。(注意使用的是python3)
首先我將最終結(jié)果給展示出來(lái):
在cmd命令行執(zhí)行:python tickets.py -dk shanghai chengdu 20161007 > result.txt

意思是:查詢(xún) 上海--成都 2016.10.07 的D和K開(kāi)頭的列車(chē)信息,并保存到 result.txt文件中;下面就是result.txt文件中的結(jié)果:

下面的將是實(shí)現(xiàn)步驟:
1、安裝第三方庫(kù) pip install 安裝:requests,docopt,prettytable
2、docopt可以用來(lái)解析從命令行中輸入的參數(shù):
"""Usage:test [-gdtkz] <from> <to> <date>Options:-h,--help 顯示幫助菜單-g 高鐵-d 動(dòng)車(chē)-t 特快-k 快速-z 直達(dá)Example:tickets -gdt beijing shanghai 2016-08-25"""import docoptargs = docopt.docopt(__doc__)print(args)# 上面 """ """ 包含中的:#Usage:# test [-gdtkz] <from> <to> <date>#是必須要的 test 是可以隨便寫(xiě)的,不影響解析
最終打印的結(jié)果是一個(gè)字典,方便后面使用:

3、獲取列車(chē)的信息
我們?cè)?2306的余票查詢(xún)的接口:
url:https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate=2016-10-05&from_station=CDW&to_station=SHH
方法為:get
傳輸?shù)膮?shù):queryDate:2016-10-05、from_station:CDW、to_station:SHH
其中城市對(duì)應(yīng)簡(jiǎn)稱(chēng)是需要另外的接口查詢(xún)得出
3.1 查詢(xún)城市對(duì)應(yīng)的簡(jiǎn)稱(chēng):
這個(gè)接口的url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.8968'
方法是get,對(duì)返回結(jié)果利用正則表達(dá)式,取出城市名和簡(jiǎn)稱(chēng)的值(返回的值類(lèi)似:7@cqn|重慶南|CRW|chongqingnan|cqn|,我們需要的就是:CRW、chongqingnan),代碼如下
parse_stations.py:
#coding=utf-8from prettytable import PrettyTableclass TrainCollection(object):"""解析列車(chē)信息"""# 顯示車(chē)次、出發(fā)/到達(dá)站、 出發(fā)/到達(dá)時(shí)間、歷時(shí)、一等坐、二等坐、軟臥、硬臥、硬座header = '序號(hào) 車(chē)次 出發(fā)站/到達(dá)站 出發(fā)時(shí)間/到達(dá)時(shí)間 歷時(shí) 商務(wù)座 一等座 二等座 軟臥 硬臥 硬座 無(wú)座'.split()def __init__(self,rows,traintypes):self.rows = rowsself.traintypes = traintypesdef _get_duration(self,row):"""獲取車(chē)次運(yùn)行的時(shí)間"""duration = row.get('lishi').replace(':','小時(shí)') + '分'if duration.startswith('00'):return duration[4:]elif duration.startswith('0'):return duration[1:]return duration@propertydef trains(self):result = []flag = 0for row in self.rows:if row['station_train_code'][0] in self.traintypes:flag += 1train = [# 序號(hào)flag,# 車(chē)次row['station_train_code'],# 出發(fā)、到達(dá)站點(diǎn)'/'.join([row['from_station_name'],row['to_station_name']]),# 成功、到達(dá)時(shí)間'/'.join([row['start_time'],row['arrive_time']]),# duration 時(shí)間self._get_duration(row),# 商務(wù)座row['swz_num'],# 一等座row['zy_num'],# 二等座row['ze_num'],# 軟臥row['rw_num'],# 硬臥row['yw_num'],# 硬座row['yz_num'],# 無(wú)座row['wz_num']]result.append(train)return resultdef print_pretty(self):"""打印列車(chē)信息"""pt = PrettyTable()pt._set_field_names(self.header)for train in self.trains:pt.add_row(train)print(pt)if __name__ == '__main__':t = TrainCollection()其中pprint這個(gè)模塊能是打印出來(lái)的信息,更加方便閱讀:
在cmd中運(yùn)行:python parse_stations.py > stations.py
就會(huì)在當(dāng)前目錄下得到stations.py文件,文件中就是站點(diǎn)名字和簡(jiǎn)稱(chēng),在stations.py文件中加入"stations = "這樣就是一個(gè)字典,方便后面的取值,下面就是stations.py文件的內(nèi)容:

3.2 現(xiàn)在獲取列車(chē)信息的參數(shù)已經(jīng)準(zhǔn)備齊了,接下來(lái)就是拿到列車(chē)的返回值,解析出自己需要的信息,比如:車(chē)次號(hào),一等座的票數(shù)等等。。,myprettytable.py
#coding=utf-8from prettytable import PrettyTableclass TrainCollection(object):"""解析列車(chē)信息"""# 顯示車(chē)次、出發(fā)/到達(dá)站、 出發(fā)/到達(dá)時(shí)間、歷時(shí)、一等坐、二等坐、軟臥、硬臥、硬座header = '序號(hào) 車(chē)次 出發(fā)站/到達(dá)站 出發(fā)時(shí)間/到達(dá)時(shí)間 歷時(shí) 商務(wù)座 一等座 二等座 軟臥 硬臥 硬座 無(wú)座'.split()def __init__(self,rows,traintypes):self.rows = rowsself.traintypes = traintypesdef _get_duration(self,row):"""獲取車(chē)次運(yùn)行的時(shí)間"""duration = row.get('lishi').replace(':','小時(shí)') + '分'if duration.startswith('00'):return duration[4:]elif duration.startswith('0'):return duration[1:]return duration@propertydef trains(self):result = []flag = 0for row in self.rows:if row['station_train_code'][0] in self.traintypes:flag += 1train = [# 序號(hào)flag,# 車(chē)次row['station_train_code'],# 出發(fā)、到達(dá)站點(diǎn)'/'.join([row['from_station_name'],row['to_station_name']]),# 成功、到達(dá)時(shí)間'/'.join([row['start_time'],row['arrive_time']]),# duration 時(shí)間self._get_duration(row),# 商務(wù)座row['swz_num'],# 一等座row['zy_num'],# 二等座row['ze_num'],# 軟臥row['rw_num'],# 硬臥row['yw_num'],# 硬座row['yz_num'],# 無(wú)座row['wz_num']]result.append(train)return resultdef print_pretty(self):"""打印列車(chē)信息"""pt = PrettyTable()pt._set_field_names(self.header)for train in self.trains:pt.add_row(train)print(pt)if __name__ == '__main__':t = TrainCollection()prettytable 這個(gè)庫(kù)是能打印出類(lèi)似mysql查詢(xún)數(shù)據(jù)顯示出來(lái)的格式,
4、接下來(lái)就是整合各個(gè)模塊:tickets.py
"""Train tickets query via command-line.Usage:tickets [-gdtkz] <from> <to> <date>Options:-h,--help 顯示幫助菜單-g 高鐵-d 動(dòng)車(chē)-t 特快-k 快速-z 直達(dá)Example:tickets -gdt beijing shanghai 2016-08-25"""import requestsfrom docopt import docoptfrom stations import stations# from pprint import pprintfrom myprettytable import TrainCollectionclass SelectTrain(object):def __init__(self):"""獲取命令行輸入的參數(shù)"""self.args = docopt(__doc__)#這個(gè)是獲取命令行的所有參數(shù),返回的是一個(gè)字典def cli(self):"""command-line interface"""# 獲取 出發(fā)站點(diǎn)和目標(biāo)站點(diǎn)from_station = stations.get(self.args['<from>']) #出發(fā)站點(diǎn)to_station = stations.get(self.args['<to>']) # 目的站點(diǎn)leave_time = self._get_leave_time()# 出發(fā)時(shí)間url = 'https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={0}&from_station={1}&to_station={2}'.format(leave_time,from_station,to_station)# 拼接請(qǐng)求列車(chē)信息的Url# 獲取列車(chē)查詢(xún)結(jié)果r = requests.get(url,verify=False)traindatas = r.json()['data']['datas'] # 返回的結(jié)果,轉(zhuǎn)化成json格式,取出datas,方便后面解析列車(chē)信息用# 解析列車(chē)信息traintypes = self._get_traintype()views = TrainCollection(traindatas,traintypes)views.print_pretty()def _get_traintype(self):"""獲取列車(chē)型號(hào),這個(gè)函數(shù)的作用是的目的是:當(dāng)你輸入 -g 是只是返回 高鐵,輸入 -gd 返回動(dòng)車(chē)和高鐵,當(dāng)不輸參數(shù)時(shí),返回所有的列車(chē)信息""" traintypes = ['-g','-d','-t','-k','-z']# result = []# for traintype in traintypes:# if self.args[traintype]:# result.append(traintype[-1].upper())trains = [traintype[-1].upper() for traintype in traintypes if self.args[traintype]]if trains:return trainselse:return ['G','D','T','K','Z']def _get_leave_time(self):"""獲取出發(fā)時(shí)間,這個(gè)函數(shù)的作用是為了:時(shí)間可以輸入兩種格式:2016-10-05、20161005"""leave_time = self.args['<date>']if len(leave_time) == 8:return '{0}-{1}-{2}'.format(leave_time[:4],leave_time[4:6],leave_time[6:])if '-' in leave_time:return leave_timeif __name__ == '__main__':cli = SelectTrain()cli.cli()好了,基本上就結(jié)束了,按照開(kāi)頭的哪樣,就能查詢(xún)你想要的車(chē)次信息了
以上所述是小編給大家介紹的Python腳本實(shí)現(xiàn)12306火車(chē)票查詢(xún)系統(tǒng),希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注