watch12306
Version:
检测12306网站,并在有余票时候通知
222 lines (211 loc) • 9.02 kB
JavaScript
;
/*
* Created by hzwangfei3 on 2016/12/5.
*/
const request = require("request");
const Type = require("./util/typeOf");
const promiseUtil = require('./util/promiseUtil');
const co = require('co');
/**
* 生成意向新的item数据
* @param isTimeoutType
* @returns {Object}
*/
function genEmptyItem(isTimeoutType){
let arr;
switch(isTimeoutType){
case 1: {
arr = "票价查询超时".split("");
break;
}
case 2: {
arr = "票价查询失败".split("");
break;
}
case 3: {
arr = "无此票价信息".split("");
break;
}
case 0:
default: {
arr = [" "," "," "," "," "]
}
}
return {
"train_no": " ",
"station_train_code": " ",
"start_station_telecode": " ",
"start_station_name": " ",
"end_station_telecode": " ",
"end_station_name": " ",
"from_station_telecode": " ",
"from_station_name": " ",
"to_station_telecode": " ",
"to_station_name": " ",
"start_time": " ",
"arrive_time": " ",
"day_difference": " ",
"train_class_name": " ",
"lishi": " ",
"canWebBuy": " ",
"lishiValue": " ",
"yp_info": " ",
"control_train_day": " ",
"start_train_date": " ",
"seat_feature": " ",
"yp_ex": " ",
"train_seat_feature": " ",
"seat_types": " ",
"location_code": " ",
"from_station_no": " ",
"to_station_no": " ",
"control_day": " ",
"sale_time": " ",
"is_support_card": " ",
"controlled_train_flag": " ",
"gg_num": " ",
"yb_num": " ",
"note": " ",
"swz_num": arr[0], //商务座
"tz_num": arr[1], //特等座
"zy_num": arr[2], //一等座
"ze_num": arr[3], //二等座
"gr_num": arr[4], //高铁软卧
"rw_num": arr[5], //软卧
"yw_num": " ", //硬卧
"rz_num": " ", //软座
"yz_num": " ", //硬座
"wz_num": " ", //无座
"qt_num": " ", //其他
"controlled_train_message": " "//备注
};
}
/**
* 根据已有的list,给每一项添加价格信息,并返回
* @param list 列表
* @param date 时间
* @returns {Array}
* 执行后,原先的list也会被更爱
*/
function * addPrice2List(list,date){
let listP = [];
let i, iLen = list.length;
for(i=0; i<iLen; i++){// 这里不能使用forEach,否则yield失效
let item = list[i];
let urlP = "https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?"
+ `train_no=${item.train_no}`
+ `&from_station_no=${item.from_station_no}`
+ `&to_station_no=${item.to_station_no}`
+ ( item.seat_types ? `&seat_types=${item.seat_types}` : "" )//非必须查询条件
+ `&train_date=${date}`;
let priceItem = yield promiseUtil.timeoutPromise(5000, new Promise((res,rej) => {
// console.log(urlP);
request({
url: urlP,
headers: {
'If-Modified-Since': 0,
'Cache-Control': 'no-cache'
},
strictSSL: false // 严格的ssl认证会导致12306请求出现循环依赖认证,而失败,原因不明
},
(err,resp,bd)=>{
if (!err && resp.statusCode == 200) {
let pData = JSON.parse(bd) || false;
// console.dir(pData);
let emptyPriceItem;
if(pData===-1){
emptyPriceItem = genEmptyItem(3);
}else{
let prices = (pData && pData.data) || {};
emptyPriceItem = genEmptyItem(0);
emptyPriceItem.swz_num = prices.A9 || emptyPriceItem.swz_num;
emptyPriceItem.tz_num = prices.P || emptyPriceItem.tz_num;
emptyPriceItem.zy_num = prices.M || emptyPriceItem.zy_num;
emptyPriceItem.ze_num = prices.O || emptyPriceItem.ze_num;
emptyPriceItem.gr_num = prices.A6 || emptyPriceItem.gr_num;
emptyPriceItem.rw_num = prices.A4 || emptyPriceItem.rw_num;
emptyPriceItem.yw_num = prices.A3 || emptyPriceItem.yw_num;
emptyPriceItem.rz_num = prices.A2 || emptyPriceItem.rz_num;
emptyPriceItem.yz_num = prices.A1 || emptyPriceItem.yz_num;
emptyPriceItem.wz_num = prices.WZ || emptyPriceItem.wz_num;
}
res(emptyPriceItem);
}else{
console.log("reject-queryTicketPrice:\r\n",err);
res(false);
}
});
})
).catch((err)=>{
console.log("出错了:\r\n", err);
return false;
});
if(priceItem){
item.swz_num = item.swz_num + (!priceItem.swz_num ? "" : ("\r\n" + priceItem.swz_num));
item.tz_num = item.tz_num + (!priceItem.tz_num ? "" : ("\r\n" + priceItem.tz_num));
item.zy_num = item.zy_num + (!priceItem.zy_num ? "" : ("\r\n" + priceItem.zy_num));
item.ze_num = item.ze_num + (!priceItem.ze_num ? "" : ("\r\n" + priceItem.ze_num));
item.gr_num = item.gr_num + (!priceItem.gr_num ? "" : ("\r\n" + priceItem.gr_num));
item.rw_num = item.rw_num + (!priceItem.rw_num ? "" : ("\r\n" + priceItem.rw_num));
item.yw_num = item.yw_num + (!priceItem.yw_num ? "" : ("\r\n" + priceItem.yw_num));
item.rz_num = item.rz_num + (!priceItem.rz_num ? "" : ("\r\n" + priceItem.rz_num));
item.yz_num = item.yz_num + (!priceItem.yz_num ? "" : ("\r\n" + priceItem.yz_num));
item.wz_num = item.wz_num + (!priceItem.wz_num ? "" : ("\r\n" + priceItem.wz_num));
}
listP.push(item);
}
return listP;
}
module.exports = (from,to,date,condition) => {
let doQuery = new Promise((resolve, reject) => {
if(!Type.isString(from) || !Type.isString(to) || !Type.isString(date)){
reject("传参有问题!")
}else{
condition = condition || {};
condition.purposeCode = condition.purposeCode ? condition.purposeCode : "ADULT";
condition.showPrice = condition.showPrice || false;
condition.onlyShowHighSpeedRail = condition.onlyShowHighSpeedRail || false;
const url = "https://kyfw.12306.cn/otn/lcxxcx/query?"
+ `purpose_codes=${condition.purposeCode}`
+ `&queryDate=${date}`
+ `&from_station=${from}`
+ `&to_station=${to}`;
// console.log(url);
request({
url: url,
headers: {
'If-Modified-Since': 0,
'Cache-Control': 'no-cache'
},
strictSSL: false
},
(error,response,body) => {
if (!error && response.statusCode == 200) {
let res = JSON.parse(body) || false;
let data = (res && res.data) || false;
let list = (data && data.datas) || [];
// 筛选高铁
if(condition.onlyShowHighSpeedRail){
list = list.filter((item)=>{
return item.station_train_code.match(/G|D|C/g);
});
}
// 增加票价信息
if(condition.showPrice){
co(function *(){
let newList = yield addPrice2List(list,date);
resolve(newList);
});
}else{
resolve(list);
}
}else{
console.log("reject-query:\r\n",error);
reject(error);
}
}
);
}
});
return promiseUtil.timeoutPromise(8000, doQuery);
};