首頁 >後端開發 >Python教學 >Python實現12306火車票查詢系統

Python實現12306火車票查詢系統

高洛峰
高洛峰原創
2017-02-24 15:12:043340瀏覽

最近我看到看到使用python實現火車票查詢,我自己也實現了,感覺收穫蠻多的,下面我就把每一步驟都詳細給分享出來。 (注意使用的是python3)

首先我將最終結果給展示出來:

在cmd命令列執行:python tickets.py -dk shanghai chengdu 20161007 > result. txt

Python實現12306火車票查詢系統

意思是:查詢上海--成都2016.10.07 的D和K開頭的列車訊息,並儲存到result.txt檔案中;下面就是result.txt文件中的結果:

Python實現12306火車票查詢系統

下面的將是實作步驟:

1、安裝第三方函式庫pip install 安裝:requests,docopt,prettytable

#2、docopt可以用來解析從命令列輸入的參數:

#
"""
Usage:
test [-gdtkz] <from> <to> <date>
Options:
-h,--help 显示帮助菜单
-g 高铁
-d 动车
-t 特快
-k 快速
-z 直达
Example:
tickets -gdt beijing shanghai 2016-08-25
"""
import docopt
args = docopt.docopt(__doc__)
print(args)
# 上面 """ """ 包含中的:
#Usage:
# test [-gdtkz] <from> <to> <date>
#是必须要的 test 是可以随便写的,不影响解析

最終列印的結果是一個字典,方便後面使用:

Python實現12306火車票查詢系統

3、取得列車的資訊

我們在12306的餘票查詢的介面:

url: 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version= 1.8968'

方法為:get

傳輸的參數:queryDate:2016-10-05、from_station:CDW、to_station:SHH

其中城市對應簡稱為需要另外的介面查詢得出

3.1 查詢城市對應的簡稱:

這個介面的url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name. js?station_version=1.8968'

  方法是get,對返回結果利用正則表達式,取出城市名和簡稱的值(返回的值類似:7@cqn|重慶南|CRW|chongqingnan|cqn|,我們需要的就是:CRW、chongqingnan),程式碼如下

parse_stations.py:

#coding=utf-8
from prettytable import PrettyTable
class TrainCollection(object):
"""
解析列车信息
"""
# 显示车次、出发/到达站、 出发/到达时间、历时、一等坐、二等坐、软卧、硬卧、硬座
header = &#39;序号 车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 软卧 硬卧 硬座 无座&#39;.split()
def __init__(self,rows,traintypes):
self.rows = rows
self.traintypes = traintypes
def _get_duration(self,row):
"""
获取车次运行的时间
"""
duration = row.get(&#39;lishi&#39;).replace(&#39;:&#39;,&#39;小时&#39;) + &#39;分&#39;
if duration.startswith(&#39;00&#39;):
return duration[4:]
elif duration.startswith(&#39;0&#39;):
return duration[1:]
return duration
@property
def trains(self):
result = []
flag = 0
for row in self.rows:
if row[&#39;station_train_code&#39;][0] in self.traintypes:
flag += 1
train = [
# 序号
flag,
# 车次
row[&#39;station_train_code&#39;],
# 出发、到达站点
&#39;/&#39;.join([row[&#39;from_station_name&#39;],row[&#39;to_station_name&#39;]]),
# 成功、到达时间
&#39;/&#39;.join([row[&#39;start_time&#39;],row[&#39;arrive_time&#39;]]),
# duration 时间
self._get_duration(row),
# 商务座
row[&#39;swz_num&#39;],
# 一等座
row[&#39;zy_num&#39;],
# 二等座
row[&#39;ze_num&#39;],
# 软卧
row[&#39;rw_num&#39;],
# 硬卧
row[&#39;yw_num&#39;],
# 硬座
row[&#39;yz_num&#39;],
# 无座
row[&#39;wz_num&#39;]
]
result.append(train)
return result
def print_pretty(self):
"""打印列车信息"""
pt = PrettyTable()
pt._set_field_names(self.header)
for train in self.trains:
pt.add_row(train)
print(pt)
if __name__ == &#39;__main__&#39;:
t = TrainCollection()

其中pprint這個模組能是印出來的信息,更方便閱讀:

在cmd中運行:python parse_stations.py > stations.py

就會在當前目錄下得到stations.py文件,文件中就是站點名字和簡稱,在stations.py檔案中加入"stations = "這樣就是一個字典,方便後面的取值,下面就是stations.py檔案的內容:

Python實現12306火車票查詢系統

##3.2 現在取得列車資訊的參數已經準備齊了,接下來就是拿到列車的回傳值,解析出自己需要的資訊,例如:車次號,一等座的票數等等。 。 ,myprettytable.py

#coding=utf-8
from prettytable import PrettyTable
class TrainCollection(object):
"""
解析列车信息
"""
# 显示车次、出发/到达站、 出发/到达时间、历时、一等坐、二等坐、软卧、硬卧、硬座
header = &#39;序号 车次 出发站/到达站 出发时间/到达时间 历时 商务座 一等座 二等座 软卧 硬卧 硬座 无座&#39;.split()
def __init__(self,rows,traintypes):
self.rows = rows
self.traintypes = traintypes
def _get_duration(self,row):
"""
获取车次运行的时间
"""
duration = row.get(&#39;lishi&#39;).replace(&#39;:&#39;,&#39;小时&#39;) + &#39;分&#39;
if duration.startswith(&#39;00&#39;):
return duration[4:]
elif duration.startswith(&#39;0&#39;):
return duration[1:]
return duration
@property
def trains(self):
result = []
flag = 0
for row in self.rows:
if row[&#39;station_train_code&#39;][0] in self.traintypes:
flag += 1
train = [
# 序号
flag,
# 车次
row[&#39;station_train_code&#39;],
# 出发、到达站点
&#39;/&#39;.join([row[&#39;from_station_name&#39;],row[&#39;to_station_name&#39;]]),
# 成功、到达时间
&#39;/&#39;.join([row[&#39;start_time&#39;],row[&#39;arrive_time&#39;]]),
# duration 时间
self._get_duration(row),
# 商务座
row[&#39;swz_num&#39;],
# 一等座
row[&#39;zy_num&#39;],
# 二等座
row[&#39;ze_num&#39;],
# 软卧
row[&#39;rw_num&#39;],
# 硬卧
row[&#39;yw_num&#39;],
# 硬座
row[&#39;yz_num&#39;],
# 无座
row[&#39;wz_num&#39;]
]
result.append(train)
return result
def print_pretty(self):
"""打印列车信息"""
pt = PrettyTable()
pt._set_field_names(self.header)
for train in self.trains:
pt.add_row(train)
print(pt)
if __name__ == &#39;__main__&#39;:
t = TrainCollection()

prettytable 這個函式庫是能印出類似mysql查詢資料顯示出來的格式,

4、接下來就是整合各個模組:tickets.py

"""Train tickets query via command-line.
Usage:
tickets [-gdtkz] <from> <to> <date>
Options:
-h,--help 显示帮助菜单
-g 高铁
-d 动车
-t 特快
-k 快速
-z 直达
Example:
tickets -gdt beijing shanghai 2016-08-25
"""
import requests
from docopt import docopt
from stations import stations
# from pprint import pprint
from myprettytable import TrainCollection
class SelectTrain(object):
def __init__(self):
"""
获取命令行输入的参数
"""
self.args = docopt(__doc__)#这个是获取命令行的所有参数,返回的是一个字典
def cli(self):
"""command-line interface"""
# 获取 出发站点和目标站点
from_station = stations.get(self.args[&#39;<from>&#39;]) #出发站点
to_station = stations.get(self.args[&#39;<to>&#39;]) # 目的站点
leave_time = self._get_leave_time()# 出发时间
url = &#39;https://kyfw.12306.cn/otn/lcxxcx/query?purpose_codes=ADULT&queryDate={0}&from_station={1}&to_station={2}&#39;.format(
leave_time,from_station,to_station)# 拼接请求列车信息的Url
# 获取列车查询结果
r = requests.get(url,verify=False)
traindatas = r.json()[&#39;data&#39;][&#39;datas&#39;] # 返回的结果,转化成json格式,取出datas,方便后面解析列车信息用
# 解析列车信息
traintypes = self._get_traintype()
views = TrainCollection(traindatas,traintypes)
views.print_pretty()
def _get_traintype(self):
"""
获取列车型号,这个函数的作用是的目的是:当你输入 -g 是只是返回 高铁,输入 -gd 返回动车和高铁,当不输参数时,返回所有的列车信息
""" 
traintypes = [&#39;-g&#39;,&#39;-d&#39;,&#39;-t&#39;,&#39;-k&#39;,&#39;-z&#39;]
# 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 trains
else:
return [&#39;G&#39;,&#39;D&#39;,&#39;T&#39;,&#39;K&#39;,&#39;Z&#39;]
def _get_leave_time(self):
"""
获取出发时间,这个函数的作用是为了:时间可以输入两种格式:2016-10-05、20161005
"""
leave_time = self.args[&#39;<date>&#39;]
if len(leave_time) == 8:
return &#39;{0}-{1}-{2}&#39;.format(leave_time[:4],leave_time[4:6],leave_time[6:])
if &#39;-&#39; in leave_time:
return leave_time
if __name__ == &#39;__main__&#39;:
cli = SelectTrain()
cli.cli()

#好了,基本上就結束了,按照開頭的哪樣,就能查詢你想要的車次資訊了

以上所述是小編給大家介紹的Python腳本實現12306火車票查詢系統,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對PHP中文網的支持!

更多Python實現12306火車票查詢系統相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn