最新Python實現12306餘票查詢系統
阿新 • • 發佈:2019-01-08
首先感謝這篇部落格的引導,但是這篇文章已經比較舊了,12306進行了改版,原始碼編排方式有了變化。12306原始碼獲取的方法可以從這篇部落格中學習,我在這裡主要貼出對於目前最新的12306的Python餘票查詢程式,可供用於學習Python的基本用法,正則表達的使用,簡單爬蟲的使用。下面是效果圖,因為我用的是windows,對命令框裡的程式碼著色比較麻煩,有興趣的朋友可以自己嘗試去給輸出的文字新增顏色。
#####################獲取站臺字典,已放在stations.py無需執行######################
#import re
#import urllib
#import ssl
#from urllib import request
#import requests
#from pprint import pprint
#ssl._create_default_https_context = ssl._create_unverified_context
#url = 'https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9018'
#req = urllib.request.Request(url)
#r = urllib.request.urlopen(req).read().decode('utf-8')
##print (r)
#stations =re.findall(r'([\u4e00-\u9fa5]+)\|([A-Z]+)',r) #匹配中文和對應的英文
#stations = dict(stations)
#stations = dict(zip( stations.keys(),stations.values()))#將匹配的內容轉化為字典
#pprint(stations) #以列的形式打印出來
############################################################ ####################
################################################################################
#功能:12306餘票查詢
#作者:wildwind_
#時間:2017.07.08
################################################################################
import re
from station import stations
import warnings
import json
import urllib
from urllib import request
import requests
from pprint import pprint
from prettytable import PrettyTable
#輸入引導
f1= input('請輸入起始城市:\n')
f = stations[f1]
t1= input('請輸入目的城市:\n')
t = stations[t1]
d1=input('請輸入出發時間: \n')
d=str('2017-')+str(d1) #這裡講年份設定為固定值,可以減少輸入操作。
print ('正在查詢'+f1+'至'+t1+'的列車,請稍等...') #個性旁白
#獲取資料
url = 'https://kyfw.12306.cn/otn/leftTicket/query?leftTicketDTO.train_date='+d+'&leftTicketDTO.from_station='+f+'&leftTicketDTO.to_station='+t+'&purpose_codes=ADULT'
warnings.filterwarnings("ignore") #這個網站是有安全警告的,這段程式碼可以忽略警告
r = requests.get(url, verify=False) #請求網址的內容
rows = r.json()['data']['result'] #將內容解析為列表
data1 = []
data = []
for m in rows:
data1.append(re.findall(r'[\u4e00-\u9fa5]訂(.*)|[\u4e00-\u9fa5]售(.*)|[\u4e00-\u9fa5]運(.*)',m))
for n in data1:
data.append(str(n).split('|'))
#製作表格
trains= PrettyTable()
trains.field_names=["車次","車站","時間","歷時","商務特等座","一等座","二等座","高階軟臥","軟臥","動臥","硬臥 ","軟座 ","硬座","無座","其他"]
#設定table的header
num = len(data) #列印列表的個數
stations_new= dict(zip(stations.values(), stations.keys()))
for row in data : #列表迴圈
trains.add_row([row[2],
'\n'.join([stations_new[row[5]],stations_new[row[6]]]),
'\n'.join([row[7], row[8]]),row[9],
row[-4] if row[-4] != '' else '--',row[-5] if row[-5] != '' else '--',
row[-6] if row[-6] != '' else '--',row[-15] if row[-15] != '' else '--',
row[-13] if row[-13] != '' else '--',row[-3] if row[-3] != '' else '--',
row[-8] if row[-8] != '' else '--',row[-11] if row[-11] != '' else '--',
row[-7] if row[-7] != '' else '--',row[-10] if row[-10] != '' else '--',
row[-14] if row[-14] != '' else '--'])
print ('查詢結束,共有 %d 趟列車。'%num ) #列表個數也就是列車個數
print (trains)