菜鳥一枚,業餘一直想作個火車票查票的H5,前端頁面什麼的已經寫好了,node+mongoDB 也寫了一個車站的接口,但前端
接下來的爬12306獲取車次信息數據一直卡住,網上的爬12306的大部分是python,node的資料比較少,並且自己也不會node.js,node
沒有任何基礎,只能看着文檔寫幾個小demo...python
nodejs爬取查票接口,獲取json數據,因爲12306的查票接口返回的數據是通過加密的,因此要再對result進行解析輸出git
寫這個的時候,找了好多,還學了python,準備用pthon爬蟲,python裏有urllib爬蟲很方便,想要用nodejs爬接口數據,github
搜了好多,被網上的一些資料給誤導了,一直用https和request請求,設置rejectUnauthorized: false忽略證書認證,還有express
什麼下載證書,讀取證書,結果一直爬不到數據,在這裏卡了很久,後來在踩了好多坑以及不斷嘗試的過程當中偶然發現其實很簡單(菜鳥o(╥﹏╥)o)npm
安裝superagentjson
npm install superagent --save
js代碼app
var superagent = require('superagent') var express = require('express'); var app = express(); var router = express.Router(); var stationobj = require('../models/query'); router.post("/", function(req,res,next){ // 前端請求用post var params = req.body var fromsta = 'BJP'; var tosta = 'HZH'; var listrpage = params.listrpage?params.listrpage:1; for(let i in stationobj){ // 把車站名解析成三字碼 fromsta = stationobj[params.FromStation] tosta = stationobj[params.ToStation] } //獲取查詢參數 var config = { time:params.FromDate,//日期格式必須是這樣 from_station:fromsta,//始發站車站代碼,這裏是北京北 end_station:tosta,//車次 }; // https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date=2018-10-20&leftTicketDTO.from_station=HZH&leftTicketDTO.to_station=SHH&purpose_codes=ADULT const url = 'https://kyfw.12306.cn/otn/leftTicket/queryO?leftTicketDTO.train_date='+config.time+'&leftTicketDTO.from_station='+config.from_station+'&leftTicketDTO.to_station='+config.end_station+'&purpose_codes=ADULT' let lists = [] superagent.get(url) .end(function(response,result){ if (result.statusCode==200) { const r = result.body const flag = r.data.flag const map = r.data.map const ress = r.data.result let priceParams = {} ress.forEach((item,index)=>{ console.log(item.split('|')) let list = {} list.train_id = item.split('|')[2] list.train_no = item.split('|')[3] for(var key in stationobj){ if(stationobj[key]===item.split('|')[4]){ list.from_station_name = key } if(stationobj[key]===item.split('|')[7]){ list.to_station_name = key } } list.start_time = item.split('|')[8] list.arrive_time = item.split('|')[9] list.duration = item.split('|')[10].split(':')[0]+'時'+item.split('|')[10].split(':')[1]+'分' list.if_can_by = item.split('|')[11] list.leave_time = item.split('|')[13] list.seat_type = item.split('|')[15] list.seat_types = item.split('|')[35] list.from_station_no = item.split('|')[16] list.to_station_no = item.split('|')[17] // 普通K:21:軟臥、 24:無座 25: 26:硬臥 27:硬座 // 普通T:19:高級軟 20:其它 21:軟臥 24:無座 26:硬臥 27:硬座 // 普通Z:19:高級軟 21:軟臥 24:無座 26:硬臥 27:硬座 // 普通Y:22:軟座 24:無座 27:硬座 // 高鐵G:23:特等 24:無座 28:二等 29:一等 30:商務 // 城際C:23:特等 24:無座 28:二等 29:一等 30:商務 // 動車D:21:軟臥 24:無座 28:二等 29:一等 31:動臥 if(list.train_no.substr(0,1)=='K'|| list.train_no.substr(0,1)=='T'|| list.train_no.substr(0,1)=='Z'){ list.zc0 = '軟臥' list.zc1 = '硬臥' list.zc2 = '硬座' list.zc3 = '無座' list.num0 = item[23]?'有票':'無票' list.num1 = item[28]?'有票':'無票' list.num2 = item[29]?'有票':'無票' list.num3 = item[26]?'有票':'無票' } if(list.train_no.substr(0,1)=='Y'){ list.zc0 = '軟座' list.zc1 = '硬座' list.zc2 = '無座' list.zc3 = '' list.num0 = item[24]?'有票':'無票' list.num1 = item[29]?'有票':'無票' list.num2 = item[26]?'有票':'無票' list.num3 = '' } if(list.train_no.substr(0,1)=='D'){ list.zc0 = '一等座' list.zc1 = '二等座' list.zc2 = '無座' list.zc3 = '' list.num0 = item[31]?'有票':'無票' list.num1 = item[30]?'有票':'無票' list.num2 = item[26]?'有票':'無票' list.num3 = '' } if(list.train_no.substr(0,1)=='G'|| list.train_no.substr(0,1)=='C'){ list.zc0 = '商務座' list.zc1 = '一等座' list.zc2 = '二等座' list.zc3 = '無座' list.num0 = item[32] || item[25]?'有票':'無票' list.num1 = item[31]?'有票':'無票' list.num2 = item[30]?'有票':'無票' list.num3 = item[26]?'有票':'無票' } lists.push(list) }) res.json({ status:true, msg:'查詢成功', data: lists }); } else { res.json({ status:false, msg:'查詢失敗', data:{} }); } }) }); module.exports = router;
獲取到原始數據,對原始數據還要進行解析,須要獲取車站對應信息的json數據,而後對應讀取,res.json接口輸出post
更多代碼詳情戳 https://github.com/leitingting08/train 更新中,這裏爲了方便,nodejs服務端代碼和前端代碼寫在同一個項目裏,
要啓動項目的話先npm install 安裝依賴,進入到前端項目命令行運行npm start打開localhost:8088端口查看,若是想查看接口運行
server目錄下的文件 node server/bin/www 打開localhost:3000端口查看,localhost:3000/query是查票接口,先這樣,前進一小步,後面持續完善...