python3 實現12306查詢餘票
阿新 • • 發佈:2018-12-31
一、查詢餘票的原理
正常使用者web瀏覽器查詢餘票通常是進入12306官網,輸入起始站、終點站、日期既可以點選查詢,如果用Python來操作則有兩種方案,一種是基於Selenium2的自動化框架控制瀏覽器實現,另一種方案則是基於Python自身的爬蟲package如request,urllib等來實現,本文實現第二種方案。
二、查詢餘票的實現
1.封裝餘票查詢URL
#查詢餘票的連結頭
query_url = "https://kyfw.12306.cn/otn/leftTicket/query?"
#查詢餘票的完整url
url=query_url+"leftTicketDTO.train_date=" +train_date+"&leftTicketDTO.from_station="+from_station+"&leftTicketDTO.to_station="+to_station+"&purpose_codes=ADULT"
2.傳送請求並讀取網頁內容
#http連線太多沒有關閉導致 Max retries exceeded with url...
#增加重試連線次數
requests.adapters.DEFAULT_RETRIES = 5
#requests使用了urllib3庫,預設的http connection是keep-alive的,requests設定False關閉。
s = requests.session()
s.keep_alive = False
#傳送查詢請求,獲取餘票網頁
r = requests.get(url,allow_redirects=True,verify=False,timeout=10)
if r.status_code==200:
# station_dict = r.json()['data']['map']
traindatas = r.json()['data']['result']
3. 解析網頁內容到指定的trainInfo資料結構
for data in traindatas:
trainInfo = {}
#解析網頁內容,抓取餘票資訊
trainRowItem = re.compile('\|([^\|]*)').findall(data)
trainInfo['train_no'] = trainRowItem[2]
trainInfo['from_station_name'] = stationDictChineseMapAbbr [trainRowItem[3]]
trainInfo['to_station_name'] = stationDictChineseMapAbbr [trainRowItem[4] ]
# trainInfo['from_station_name'] = trainRowItem[3]
# trainInfo['to_station_name'] = trainRowItem[4]
trainInfo['start_time'] = trainRowItem[7]
trainInfo['arrive_time'] = trainRowItem[8]
trainInfo['duration'] = trainRowItem[9]
trainInfo['swz_num'] = trainRowItem[31]
...
4.輸出餘票資料結構內容trainInfo到終端
#設定輸出格式
header = '序號 車次 出發站 到達站 出發時間 到達時間 歷時 商務座 一等座 二等座 高階軟臥 軟臥 動臥 硬臥 硬座 無座'.split()
pt = PrettyTable()
pt._set_field_names(header)
for i,trainInfo in enumerate(trainInfoList):
pt.add_row([i,trainInfo['train_no'],trainInfo['from_station_name'],trainInfo['to_station_name'],trainInfo['start_time'],
trainInfo['arrive_time'],trainInfo['duration'],trainInfo['swz_num'],
trainInfo['zy_num'],trainInfo['ze_num'],trainInfo['gjrw_num'],trainInfo['rw_num'],trainInfo['dw_num'],
trainInfo['yw_num'],trainInfo['yz_num'],trainInfo['wz_num']])
#終端輸出
print(pt)