用nodejs编写股票数据爬虫

以下代码仅仅用作学习交流,请勿用作其他用途


?基础类 getBoard
 /*************************************************************
*
*- Copyright (c), 股票数据API接口基础Class, 2018, lopo
*- FileName : default.js
*- Author : 罗波 Version : 1.0 Date:2018-8-4
*- Descripttion : 股票 Node Express
*- Other : 数据来源-东方财富
*- JSVersion : ES6
*- Modules :
* 1.request
* 2.cheerio
*
*----------------------------------------------------------
*
*- Function List :
* - tools
* 1. getCodeExchange
*
*- Class List :
* 1. boards
*
*- History :
* <Author> <Date> <Desc> <Modi>
*
**************************************************************/
'use strict'
const request = require('request-promise-native');
const { getCodeExchange } = require('../utils/tools');

/**
* 基础配置
*
* @class getBoards
*/
class getBoards {
// 基础参数
constructor() {
// - stockSty : ['列表概览','个股详细']
this.reqOpt = {
uri: 'http://nufm.dfcfw.com/EM_Finance2014NumericApplication/JS.aspx',
qs: {
type: 'CT',
token: '64a483cbad8b666efa51677820e6b21c',
js: '({data:[(x)],totle:(tot)})',
'_': (new Date()).valueOf(),
}
};
// _rp_options.qs
this.request = request.defaults(this.reqOpt);
// - pageFn : p/当前页 ps/页数据量 st/排序字段 sr/排序方式
//* @param {Number} p 当前页
//* @param {Number} ps 每页数量 20
//* @param {String} st 排序字段
//* @param {Number} sr 排序方式 -1,1
this.pageOpt = (params) => {
return {
qs: {
p: params[0] || '1',
ps: params[1] || '20',
st: params[2] || '(ChangePercent)',
sr: params[3] || '-1'
}
}
};
/**
*
* @param {Objec} cmdMap 参数比对数组
* @param {Object} params page参数
* @param {String} type 参数
* @param {String} sty 展示方式
*
* @returns promise
*
* @memberof boards
*/
this.boradFn = (cmdMap, ...params) => (type, sty = this.stockSty[0]) => {
const boardMap = cmdMap;
if (!boardMap[type]) return { 'err': 'TypeError' };
const opt = this.pageOpt([...params]);
Object.assign(opt.qs, {
'cmd': boardMap[type],
'sty': sty
});
return this.getDatas({...opt })
};
};
/**
*格式化cmd配置亲求
*
* @param {String,Arrary} codes 股票代码格式化
* @returns String
* @memberof boards
*/
setCodeCmd(codes) {
if (codes.includes(',')) codes = codes.split(',');
return Array.isArray(codes) ? codes.reduce((a, b, i) => a += `${getCodeExchange(b)}${i<codes.length-1?',':''}`, '') : `${getCodeExchange(codes)}`
};
/**
*request 请求函数
*
* @param {Object} opt 请求配置
* @returns promise
* @memberof boards
*/
async getDatas(opt) {
try {
const datas = await this.request({...opt });
return await eval(datas);
} catch (error) {
return { 'err': 'NETError' }
}
};
}
module.exports = getBoards
辅助类 tool.js
const fixMoney = (money, fix = 2) => (money / (money.length < 8 ? 10000 : 100000000)).toFixed(fix) + (money.length < 8 ? '万' : '亿');
//
const timeout = async(ms) => {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
};
const getCodeExchange = (code, type = "stock") => {
let codes = code.substr(0, 3);
if (type === 'stock') return (codes === '000' || codes === '002') && `${code}2` || (codes === '600' || codes === '601' || codes === '603') && `${code}1` || `${code}2`
else return codes === '399' ? `${code}2` : `${code}1`
};
module.exports = {
fixMoney,
timeout,
getCodeExchange
}
基金 fund.js
 /*************************************************************
*
*- Copyright (c), 股票数据API接口 基金, 2018, lopo
*- FileName : default.js
*- Author : 罗波 Version : 1.0 Date:2018-8-4
*- Descripttion : 股票 Node Express
*- Other : 数据来源-东方财富
*- JSVersion : ES6
*
*----------------------------------------------------------
*- Class List :
* 1.getBoard
*
*- History :
* <Author> <Date> <Desc> <Modi>
*
**************************************************************/
'use strict'
const getBoard = require('../../utils/getBoard');
//
class funds extends getBoard {
/**
* 封闭基金
*
* @param {string} [type='ALL']
* @param {*} params
* @returns
* @memberof futures
*/
// 封闭基金 ETF基金 LOF基金
async FUND_Board(type = 'ALL', ...params) {
const ENERGYMap = {
'CLOSE_END': 'C.__285002',
'ETF': 'C.__2850013',
'LOF': 'C.__2850014'
};
const datas = this.boradFn(ENERGYMap, ...params);
return datas(type, 'FCOIATC')
};

}
const client = new funds();?
// client.FE_DCE_Board('ALL', 1, 50).then(res => console.log(res));
client.FUND_Board('CLOSE_END', 1, 50).then(res => console.log(res))
期货类 futures.js
 /*************************************************************
*
*- Copyright (c), 股票数据API接口 期货, 2018, lopo
*- FileName : default.js
*- Author : 罗波 Version : 1.0 Date:2018-8-4
*- Descripttion : 股票 Node Express
*- Other : 数据来源-东方财富
*- JSVersion : ES6
*
*----------------------------------------------------------
*- Class List :
* 1.getBoard
*
*- Class List :
* 1. futures
*
*- History :
* <Author> <Date> <Desc> <Modi>
*
**************************************************************/
'use strict'
const getBoard = require('../../utils/getBoard');
//
class futures extends getBoard {
constructor() {
super();
this.fecSty = ['FCHKEGL', 'FCFL4O']
};
/**
* 国内期货数据
*
* @param {*} type
* @param {*} params
* @returns
* @memberof boards
*/
//[上期所所有,["沪锌", "沪铅", "石油沥青", "沪金", "螺纹钢", "沪银", "热轧卷板", "沪铝", "沪锡", "橡胶", "沪铜", "沪镍", "线材", "燃油","原油"]]
async FE_SH_Board(type, ...params) {
const FESHMap = {
ALL: 'C.SHFE',
ZN: 'C.F_SHFE_ZN',
PB: 'C.F_SHFE_PB',
BU: 'C.F_SHFE_BU',
AU: 'C.F_SHFE_AU',
RB: 'C.F_SHFE_RB',
AG: 'C.F_SHFE_AG',
HC: 'C.F_SHFE_HC',
AL: 'C.F_SHFE_AL',
SN: 'C.F_SHFE_SN',
RU: 'C.F_SHFE_RU',
CU: 'C.F_SHFE_CU',
NI: 'C.F_SHFE_NI',
WR: 'C.F_SHFE_WR',
FU: 'C.F_SHFE_FU',
INE: 'C.INE',
};
const datas = this.boradFn(FESHMap, ...params);
return datas(type, this.fecSty[1])
};
// 大商所 ["焦炭","聚丙烯","铁矿石","鸡蛋","豆油","豆一","棕榈油","纤维板","聚氯乙烯","聚乙烯","豆粕","豆二","焦煤","玉米","胶合板","玉米淀粉"]
async FE_DCE_Board(type, ...params) {
const FEDCEMap = {
"ALL": 'C.DCE',
"J": "C.F_DCE_J",
"PP": "C.F_DCE_PP",
"I": "C.F_DCE_I",
"JD": "C.F_DCE_JD",
"Y": "C.F_DCE_Y",
"A": "C.F_DCE_A",
"P": "C.F_DCE_P",
"FB": "C.F_DCE_FB",
"V": "C.F_DCE_V",
"L": "C.F_DCE_L",
"M": "C.F_DCE_M",
"B": "C.F_DCE_B",
"JM": "C.F_DCE_JM",
"C": "C.F_DCE_C",
"BB": "C.F_DCE_BB",
"CS": "C.F_DCE_CS"
};
const datas = this.boradFn(FEDCEMap, ...params);
return datas(type, this.fecSty[1])
};
// ["一号棉花","强麦","棉纱","苹果","早籼稻","硅铁","普麦","晚籼稻","甲醇","菜粕","玻璃","锰硅","PTA","动力煤","粳稻","白糖","菜籽","菜油"]
async FE_CZCE_Board(type, ...params) {
const CZCEMap = {
"ALL": "C.CZCE",
"CF": "C.F_CZCE_CF",
"WH": "C.F_CZCE_WH",
"CY": "C.F_CZCE_CY",
"AP": "C.F_CZCE_AP",
"ER": "C.F_CZCE_ER",
"SF": "C.F_CZCE_SF",
"WT": "C.F_CZCE_WT",
"LR": "C.F_CZCE_LR",
"MA": "C.F_CZCE_MA",
"RM": "C.F_CZCE_RM",
"FG": "C.F_CZCE_FG",
"SM": "C.F_CZCE_SM",
"TA": "C.F_CZCE_TA",
"ZC": "C.F_CZCE_ZC",
"JR": "C.F_CZCE_JR",
"SR": "C.F_CZCE_SR",
"RS": "C.F_CZCE_RS",
"OI": "C.F_CZCE_OI"
};
const datas = this.boradFn(CZCEMap, ...params);
return datas(type, this.fecSty[1])
};
// 中金所
async FE_CFFEX_Board(type, ...params) {
const FEMap = {
CFFEX_ALL: 'R._168|_169',
CFFEX_5: 'C._TF_FO',
CFFEX_10: 'C._T_FO',
CFFEX_IC_FO: 'C._IC_FO',
CFFEX_IF_FO: 'C._IF_FO',
CFFEX_IH_FO: 'C._IH_FO'
}
const datas = this.boradFn(FEMap, ...params);
return datas(type, this.fecSty[1])
};
/**
* 香港期货
*
* @param {*} type
* @param {*} params
* @returns
* @memberof boards
*/
// async FECHKBoard(type, ...params) {
// // [港交所,指数期货]
// const FEMap = {
// HKSTOCKF: 'C.HEX.HKSTOCKF',
// HKINDEXF: 'C.HEX.HKINDEXF',
// }
// const datas = this.boradFn(FEMap, ...params);
// return datas(type, this.fecSty[1])
// };
// ["玉米","豆油","超国债","迷你玉米","年美国债","小型道指","燕麦","小麦","十年美国债","大豆","豆粕","五年美国债","乙醇","稻谷","迷你大豆","迷你小麦","COMEX铜","COMEX白银","COMEX黄金","微型黄金","迷你黄金","迷你白银","重柴油","布伦特原油","天然气","场内锌","综合铜","伦铜现","LmeS_铜","场内铜","LmeS_锌","LmeS_铅","综合铅","综合镍","伦镍现","LmeS_镍","伦铅现","场内铝","伦铝现","场内镍","LmeS_铝","场内铅","综合铝","场内锡","综合锌","伦锌现","LmeS_锡","综合锡","伦锡现","LmeS合金","棕榈油","糖号","棉花","NYMEX汽油","NYMEX燃油","迷你原油","NYMEX钯金","NYMEX铂金","热轧钢卷","NYMEX原油","现货黄金","现货白银","现货铂金","A期指","号合成胶","cst燃油","号烟片胶","日铂金","日煤油","日黄金","日原油","日钯金","日白银","日汽油","日橡胶"]
async FE_GLO_Board(type, ...params) {
const FEGLOMap = {
"ZC": "C.UF_COBOT_ZC",
"ZL": "C.UF_COBOT_ZL",
"UL": "C.UF_COBOT_UL",
"XC": "C.UF_COBOT_XC",
"US": "C.UF_COBOT_US",
"YM": "C.UF_COBOT_YM",
"ZO": "C.UF_COBOT_ZO",
"ZW": "C.UF_COBOT_ZW",
"TY": "C.UF_COBOT_TY",
"ZS": "C.UF_COBOT_ZS",
"ZM": "C.UF_COBOT_ZM",
"FV": "C.UF_COBOT_FV",
"EH": "C.UF_COBOT_EH",
"ZR": "C.UF_COBOT_ZR",
"XK": "C.UF_COBOT_XK",
"XW": "C.UF_COBOT_XW",
"HG": "C.UF_COMEX_HG",
"SI": "C.UF_COMEX_SI",
"GC": "C.UF_COMEX_GC",
"MGC": "C.UF_COMEX_MGC",
"QO": "C.UF_COMEX_QO",
"QI": "C.UF_COMEX_QI",
"G": "C.UF_IPE_G",
"B": "C.UF_IPE_B",
"M": "C.UF_IPE_M",
"LZN": "C.UF_LME_LZN",
"LCP": "C.UF_LME_LCP",
"CPR": "C.UF_LME_CPR",
"LLD": "C.UF_LME_LLD",
"LNK": "C.UF_LME_LNK",
"NKR": "C.UF_LME_NKR",
"LDR": "C.UF_LME_LDR",
"LAL": "C.UF_LME_LAL",
"ALR": "C.UF_LME_ALR",
"LDD": "C.UF_LME_LDD",
"LTN": "C.UF_LME_LTN",
"ZHR": "C.UF_LME_ZHR",
"TNR": "C.UF_LME_TNR",
"LAA": "C.UF_LME_LAA",
"MPM": "C.UF_MDEX_MPM",
"SB": "C.UF_NYBOT_SB",
"CT": "C.UF_NYBOT_CT",
"RB": "C.UF_NYMEX_RB",
"HO": "C.UF_NYMEX_HO",
"QM": "C.UF_NYMEX_QM",
"PA": "C.UF_NYMEX_PA",
"PL": "C.UF_NYMEX_PL",
"HR": "C.UF_NYMEX_HR",
"CL": "C.UF_NYMEX_CL",
"AU": "C.UF_SGE_AU",
"AG": "C.UF_SGE_AG",
"PT": "C.UF_SGE_PT",
"CN": "C.UF_SGX_CN",
"TF": "C.UF_SGX_TF",
"FB": "C.UF_SGX_FB",
"RT": "C.UF_SGX_RT",
"JPL": "C.UF_TOCOM_JPL",
"JKE": "C.UF_TOCOM_JKE",
"JAU": "C.UF_TOCOM_JAU",
"JCO": "C.UF_TOCOM_JCO",
"JPA": "C.UF_TOCOM_JPA",
"JAG": "C.UF_TOCOM_JAG",
"JGL": "C.UF_TOCOM_JGL",
"JRU": "C.UF_TOCOM_JRU"
}
const datas = this.boradFn(FEGLOMap, ...params);
return datas(type, this.fecSty[1])
};
/**
* 金融期货GOL
* @param {*} type
* @param {*} params
*/
async FE_FINANCE_Board(type = 'ALL', ...params) {
const FINAMap = {
'ALL': 'R._ZJMF_Main_MonetaryFutures|_UMF_Main_MonetaryFutures'
};
const datas = this.boradFn(FINAMap, ...params);
return datas(type, this.fecSty[1])
};
/**
* 能源化工
*
* @param {string} [type='ALL']
* @param {*} params
* @returns promise
* @memberof futures
*/
async FE_ENERGY_Board(type = 'ALL', ...params) {
const ENERGYMap = {
'ALL': 'R._F_MAIN_ENERGY|_UF_MAIN_ENERGY'
};
const datas = this.boradFn(ENERGYMap, ...params);
return datas(type, this.fecSty[1])
};
/**
* 金属钢材
*
* @param {string} [type='ALL']
* @param {*} params
* @memberof futures
*/
async FE_METAL_Board(type = 'ALL', ...params) {
const METALMap = {
'ALL': 'R._F_MAIN_METAL|_UF_MAIN_METAL'
};
const datas = this.boradFn(METALMap, ...params);
return datas(type, this.fecSty[1])
};
//
/**
* 农产品食品原料
*
* @param {string} [type='ALL']
* @param {*} params
* @returns
* @memberof futures
*/
async FE_FARM_Board(type = 'ALL', ...params) {
const FARMMap = {
'ALL': 'R._F_MAIN_FARMPRODUCE|_UF_MAIN_FARMPRODUCE'
};
const datas = this.boradFn(FARMMap, ...params);
return datas(type, this.fecSty[1])
}
}
const client = new futures();?
// client.FE_DCE_Board('ALL', 1, 50).then(res => console.log(res));
client.FE_FARM_Board().then(res => console.log(res))
股票类 stocks.js
 /*************************************************************
*
*- Copyright (c), 股票数据API接口, 2018, lopo
*- FileName : stocks.js 股票
*- Author : 罗波 Version : 1.0 Date:2018-8-4
*- Descripttion : 股票 Node Express
*- Other : 数据来源-东方财富
*- JSVersion : ES6
*- Modules :
* 1.request
*
*----------------------------------------------------------
*- Class List :
* 1.getBoard
*- Function List :
* - tools
* 1. getCodeExchange
*
*- Class List :
* 1. stocks
*
*- History :
* <Author> <Date> <Desc> <Modi>
*
**************************************************************/
'use strict'
const getBoard = require('../../utils/getBoard');
//
class stocks extends getBoard {
constructor() {
super();
this.stockSty = ['FCOIATC', 'CTBF', 'FPGBKI', 'CTF', 'FCABHL', 'FCRH']
};
/**
* 沪深个股集合
*
* - params
* @param {String|Array} code 股票代码 可以为 600000 | 600000,600001 | [600000,600001]
*
* - Desc 多用于个股自选接口用
**/
StockList(code) {
const opt = {
qs: {
cmd: this.setCodeCmd(code),
sty: this.stockSty[1]
}
}
return this.getDatas({...opt })
};
/**
* 沪深股市
*
* @param {String} type 指定字符串 1
*
* @returns Promise
*
* @memberof boards
*/
async HSBoard(type, ...params) {
// [沪深A股,上证A股,深证A股,新股,中小板,创业板,沪AB股比价,深AB股比价,B股,AB股比价,风险警示,两网及退市]
const boardMap = {
CHSA: 'C._A',
CHA: 'C.2',
CSA: 'C._SZAME',
CHSN: 'C.BL05011',
CHSZX: 'C.13',
CHSCY: 'C.80',
CHAB: 'C._ABPCSHZ',
CHSAB: 'C._ABPCSZZ',
CHSB: 'C._B',
CHSAB_AH: 'C._ABPCSHZ',
CHSW: 'C._AB_FXJS',
CHSE: 'R.__40|__42'
};
const datas = this.boradFn(boardMap, ...params);
return datas(type, type !== 'CHSAB_AH' ? this.stockSty[0] : this.stockSty[4])
};
/**
* 行业板块
* <type> <name> <desc> <default> <Must>
* @param {String} type 指定字符串 1
* @param {Number} p 当前页
* @param {Number} ps 每页数量 20
* @param {String} st 排序字段
* @param {Number} sr 排序方式 -1,1
*
* @returns promise
*
* @memberof boards
*/
async BKBoard(type, ...params) {
// [行业板块,地域板块,概念板块]
const BKMap = {
BKHY: 'C._BKHY',
BKDY: 'C._BKDY',
BKGN: 'C._BKGN'
};
const datas = this.boradFn(BKMap, ...params);
return datas(type, this.stockSty[2])
};
/**
* 国内指数
*
* @param {*} type
* @param {*} params
* @returns promise
* @memberof boards
*/
async ZSBoard(type, ...params) {
// [上证指数,深证指数,指数成分]
const ZSMap = {
ZSSH: 'C.1',
ZSSZ: 'C.5',
ZSALL: 'C.IE.ALL'
};
const datas = this.boradFn(ZSMap, ...params);
return datas(type)
};
/**
* 港股通
*
* @param {*} type
* @param {*} params
* @returns promise
* @memberof boards
*/
async HSGTBoard(type, ...params) {
// [沪股通,深股通,港股通(沪),港股通(深)]
const HSGTMap = {
SH_HK: 'C.BK07071',
SZ_HK: 'C.BK08041',
HK_SH: 'C.MK0144',
HK_SZ: 'C.MK0146',
};
const datas = this.boradFn(HSGTMap, ...params);
return datas(type)
};
/**
* 港股列表
*
* @param {*} type
* @param {*} params
* @returns promise
* @memberof boards
*/
async HKBoard(type, ...params) {
// [所有港股,主力港股,创新港股,知名港股,港股蓝筹,港股红筹,港股红筹指数成分股,国企股,国企指数成分股,港股通成分股,HS综合大型,HS综合中型,AH比价,ADR,恒生指数]
// 比价参数 client.HKBoard('AH_COMP', 1, 5, '(AB/AH/HKD)').then(res => console.log(res))
const HKMap = {
HKALL: 'C._HKS',
HKMAIN: 'C.MK0107',
HKGEM: 'C.__28GEM',
HKWELL: 'C.MK0009',
HKBLUE: 'C.MK0104',
HKRED: 'C.MK0102',
HKRED_COMP: 'C.__28HSCIINDEX',
HKSTATE: 'C.__28HSCEI',
HKSTATE_COMP: 'C.__28HSCEIINDEX',
HK_COMP: 'C.MK0144',
HSI_LG_COMP: 'C.MK0141',
HSI_MD_COMP: 'C.MK0142',
AH_COMP: 'C._AHH',
HK_ADR: 'C._ADRA',
HS_ZS: 'R.HKI|HKIN|HS',
HK_WARRANTS: 'C._HKW'
};
const datas = this.boradFn(HKMap, ...params);
return datas(type, type !== 'AH_COMP' || type !== 'HS_ZS' || type !== 'HK_WARRANTS' ? this.stockSty[3] : this.stockSty[4])
};
/**
* 美股
*
* @param {*} type
* @param {*} params
* @returns promise
* @memberof boards
*/
async USBoard(type, ...params) {
// [全部美股,[知名美股,[美科技股,金融,医药食品,媒体,汽车能源,制造零售]],[中国概念,中国互联网],美股指数]
const USMap = {
USALL: 'C._UNS',
USWELL: 'R.MK0216|MK0217|MK0218|MK0219|MK0220|MK0221',
USTECH: 'C.MK0216',
USFINA: 'C.MK0217',
USMEDI_FOOD: 'C.MK0218',
USMEDIA: 'C.MK0219',
USRAUTO_ENGNIN: 'C.MK0220',
USMADE_RETA: 'C.MK0221',
US_CN: 'R.MK0214|MK0212|MK0213|MK0202',
US_CNET: 'C.MK0202',
USZS: 'C._UI_MAP_USOA'
}
const datas = this.boradFn(USMap, ...params);
return datas(type)
};
/**
* 全球指数
*
* @param {*} type
* @param {*} params
* @returns promise
* @memberof boards
*/
async GLOBoard(type, ...params) {
// [亚洲,美洲,欧洲,澳洲]
const GLOMap = {
ASIA: 'R.0000011,3990012,0003001,3990062,3990052,HSI5,HSCEI5,HSCCI5|_UI_MAP_ASIA',
AMERICA: 'C._UI_MAP_AME',
EURO: 'C._UI_MAP_EUR',
AUSTRALIA: 'C._UI_MAP_AUS'
}
const datas = this.boradFn(GLOMap, ...params);
return datas(type, this.stockSty[5])
};
};
module.exports = stocks;
const client = new stocks();
// client.getStockFullInfo('600803,600601').then(res => console.log(res));
// client.HSBoard('CHSA', 1, 2).then(res => console.log(res));
// client.HSBoard('CHSAB_AH', 1, 2, '(AB/AH/USD)').then(res => console.log(res));
// client.BKBoard('BKDY', 1, 5).then(res => console.log(res));
client.ZSBoard('ZSSH', 1, 15).then(res => console.log(res));
// client.HSGTBoard('HK_SH', 1, 5).then(res => console.log(res));
// client.HKBoard('AH_COMP', 1, 5, '(AB/AH/HKD)').then(res => console.log(res));
// client.HKBoard('HK_WARRANTS', 1, 5).then(res => console.log(res));
// client.ZSHSBoard('ALL', 1, 5).then(res => console.log(res));
// client.USBoard('USZS', 1, 5).then(res => console.log(res));
// client.HSBoard('CHSA', 1, 10000).then(res => console.log(res))
// client.FECHKBoard('HKSTOCKF').then(res => console.log(res));

0 个评论

要回复文章请先登录注册