監控網址: 新浪股票接口http://www.cnblogs.com/kingwolfofsky/archive/2011/08/14/2138081.html
所用技術:js、JQuery、Notification瀏覽器消息推送
所需環境:windows、IIS或Linux,Apache;Mac也可以,只是一些html和js文件,要求不高,能搭建起網站就行;
Notification瀏覽器消息推送參考網址:https://blog.csdn.net/weixin_33985679/article/details/89559580,消息推送只能在https網站有效。
新浪股票接口參考文檔:https://www.cnblogs.com/phpxuetang/p/4519446.html
如參考代碼涉及侵權,請聯系QQ:565539567,進行刪除原貼。本帖分享此次開發經驗,僅供大家參考!
需求:由於本人初次入股市,不懂行情,故想找一個實時監控股票價格,如波動較大則及時通知我。雖然很多手機App都有通知功能,但我只是想看看波動情況,每次都要看手機不太方便,所以想找一個web端的,因為工作的時候,PC上直接提示會方便的多。但苦於找了半天都沒有找到合適的網站有提供,只能自己擼一個了。
背景:找到市面上提供了實時股票數據的網站,這是有很多的,但大多都不是https的由於瀏覽器的同源安全策略導致Notification消息推送不可用,那沒有提示就沒法愉快的玩耍了,如新浪的:http://finance.sina.com.cn/realstock/company/sz002271/nc.shtml?from=BaiduAladin,找了半天終於找到了一個https的網站:https://www.laohu8.com/stock/002271,剛高興的把Notification消息推送的腳本加進去,坐等提示,結果半天沒反應,然后發現這個網站居然不是實時動態更新數據的,坑啊。沒辦法,也沒耐心接着找了,只是一個爬取數據,簡單分析,給出提醒,功能也不難,索性就自己擼一個出來。
開始:前端
在head中引入<script type="text/javascript" src="http://hq.sinajs.cn/list=sz002271" charset="gb2312"></script>,這里用來獲取股票的數據 
瀏覽器消息推送代碼實現,這段代碼用到了瀏覽器通知,因為瀏覽器安全機制,只能在https或本地localhost中有效,如果發布后要將網站添加SSH證書,否則http中將不起作用。
var PERMISSON_GRANTED = 'granted';
var PERMISSON_DENIED = 'denied';
var PERMISSON_DEFAULT = 'default'; Notification.requestPermission(function (res) { if (res === PERMISSON_GRANTED) { console.log('提醒開啟成功!') } }); //瀏覽器消息推送 function createNotify(title, options) { if (Notification.permission === PERMISSON_GRANTED) { notify(title, options); } else { Notification.requestPermission(function (res) { if (res === PERMISSON_GRANTED) { notify(title, options); } }); } function notify($title, $options) { var notification = new Notification($title, $options); } }
動態加載js包,用來實時刷新獲取股票信息
function loadJS(url, callback) {
var script = document.createElement('script'),
fn = callback || function () { }; script.type = 'text/javascript'; //IE if (script.readyState) { script.onreadystatechange = function () { if (script.readyState == 'loaded' || script.readyState == 'complete') { script.onreadystatechange = null; fn(); } }; } else { //其他瀏覽器 script.onload = function () { fn(); }; } script.src = url; document.getElementsByTagName('head')[0].children[3].remove(); document.getElementsByTagName('head')[0].appendChild(script); }
設置監控參數,簡單分析並定時刷新股票信息
var _time = 10,//定時秒數
boval = 10,//波動值金額¥
buy_num = 500,//買入股數 buy_money = 7.72,//買入價格,0取開盤價,-1取昨收價 _val = 100;//記錄最近數據個數 var intervalId,//定時器 num = 0, //次數 today_amount = 0,//今日盈虧 maxVal = 0, minVal = 0; val = [];//值 var zs_price = elements[2];//昨收 var jk_price = elements[1];//今開 var name = elements[0]; $(document).ready(function () { intervalId = window.setInterval(function () { elements = hq_str_sz002271.split(","); var _code = 'hq_str_' + $('#code').val(); var a = $(this)[0].frames['' + _code]; if (a != undefined) { elements = a.split(','); } if (document.title != elements[0]) { maxVal = 0; minVal = 0; } zs_price = elements[2];//昨收 jk_price = elements[1];//今開 document.title = elements[0]; num++; var zx_price = elements[3]; name = elements[0]; buy_money = parseFloat($('#price').val()).toFixed(2); buy_num = parseInt($('#num').val()); boval = parseFloat($('#boval').val()).toFixed(2); $('#kp_price').text(jk_price); var no = num % _val; var preno = (num - 1) % _val; var startval = buy_money; if (buy_money == 0) { startval = jk_price; } else if (buy_money == -1) { startval = zs_price; } var tarval = ((parseFloat(zx_price) - startval) * buy_num).toFixed(2); val[no] = tarval; if (parseFloat(tarval) > parseFloat(maxVal)) maxVal = parseFloat(tarval); if (parseFloat(tarval) < parseFloat(minVal) || minVal == 0) minVal = parseFloat(tarval); if (num > 1) { if (Math.abs(val[no] - val[preno]) > boval) { var d = new Date(); today_amount = ((parseFloat(zx_price) - zs_price) * buy_num).toFixed(2); var msg1 = '股價:' + zx_price + ';當前盈虧:' + tarval.toString() + ';最高;' + maxVal.toString() + ';最低:' + minVal.toString() + ';波動:' + (val[no] - val[preno]).toString(); console.log('時間:' + d.toLocaleString() + ';' + name + '第' + no.toString() + '次,最近2次波動大於' + boval.toString() + ',請留意動向!上次:' + val[preno].toString() + ';本次:' + val[no].toString() + ';波動:' + (val[no] - val[preno]).toString()); createNotify(name + '預警通知', { body: msg1 }); } } today_amount = ((parseFloat(zx_price) - zs_price) * buy_num).toFixed(2); $('#real_price').text(zx_price); $('#real_amount').text(tarval); var msg = name + '當前股價:' + zx_price + ';當前盈虧:' + tarval.toString() + ';今日盈虧:' + today_amount.toString() + ';最高;' + maxVal.toString() + ';最低:' + minVal.toString(); console.log(msg); //刷新接口 loadJS('http://hq.sinajs.cn/list=' + $('#code').val(), function () { }); }, 1000 * _time); })
到此核心業務代碼就已經寫完了,是不是很簡單。前端頁面做的很簡單
效果圖 

現在就可以干自己的事了,如果股價有異常,會收到通知的,可以根據自己的需求修改來達到自己想要的效果。只要瀏覽器這個頁面不關閉,頁面可以最小化。
免責聲明:股市有風險,投資需謹慎。本代碼只提供參考,請根據自己情況仔細分析調整,如因本代碼導致您操作異常,本作者不承擔任何責任,請自行做好充分測試;
源碼地址:https://gitee.com/lp006/AutoWachtStork
小結:1、接口為什么要使用script腳本引入的方式?
因為站點不同,涉及到js跨域操作,如果使用iframe方式,會導致js跨域獲取失敗,因為接口后端是沒有把我們的請求網站添加為可信任的站點。我們不能改變提供方,就只能改變我們自己了,用腳步引入方式不受跨域限制;想詳細了解js跨域問題的,可以參考不要再問我js跨域的問題了
2、為什么要動態加載js包?
因為我們是通過js包來獲取接口數據的,瀏覽器在解析js包時會獲取接口的返回數據,但只在解析時獲取,這樣就只能獲取一次接口數據,我們需要的是實時變化的股票數據,所以要在定時器中動態加載,這樣才能保證是最新的數據。為避免加載的js重復過多,所以在加載前需要先移除之前的js包。
3、直接打開源碼中的demo.html沒有提示?
需要搭建本地網站,Notification瀏覽器消息推送只能在https和localhost中有效。如需遠程訪問,需在搭建站點時,添加SSH證書。
