Previous on 系列教程:
互聯網金融爬蟲怎么寫-第一課 p2p網貸爬蟲(XPath入門)
互聯網金融爬蟲怎么寫-第二課 雪球網股票爬蟲(正則表達式入門)
互聯網金融爬蟲怎么寫-第三課 雪球網股票爬蟲(ajax分析)
哈哈,我又來了,話說出教程就是這么任性,咱們乘熱打鐵,把上節課分析完成但是沒寫的代碼給完成了!
工具要求與基礎知識:
工具要求:
教程中主要使用到了 1、神箭手雲爬蟲 框架 這個是爬蟲的基礎,2、Chrome瀏覽器和Chrome的插件XpathHelper 這個用來測試Xpath寫的是否正確 3、Advanced REST Client用來模擬提交請求
基礎知識:
本教程中主要用到了一些基礎的js和xpath語法,如果對這兩種語言不熟悉,可以提前先學習下,都很簡單。
三步走
還記得我們在遙遠的電商系列爬蟲教程的第一課里提到具體寫爬蟲的幾個步驟嗎?我們沿着路徑再來走一遍:
第一步:確定入口URL
暫且使用這個第一頁的ajax的url鏈接:
http://xueqiu.com/stock/cata/stocklist.json?page=1&size=30&order=desc&orderby=percent&type=11%2C12
第二步:區分內容頁和中間頁
這次大家有點犯難了,雖然說每一個股票都有一個單獨的頁面,但是列表頁的信息已經蠻多的了,光爬取列表頁信息就已經夠了,那怎么區分內容頁和中間頁呢?其實我們只需要將內容頁和中間頁的正則設置成一樣的既可。如下:
http://xueqiu.com/stock/cata/stocklist\\.json\\?page=\\d+&size=30&order=desc&orderby=percent&type=11%2C12
在提醒大家一下,這里之所以轉義符用了兩個是因為在神箭手中,設置正則時,是字符串設置,需要對轉義符再做一次轉義。
第三步:內容頁抽取規則
由於ajax返回的是json,而神箭手是支持jsonpath的提取方式的,因此提取規則就很簡單了。不過這里要特殊注意的是,由於我們是在列表頁抽取數據,因此數據最頂層相當於是一個列表,我們需要在頂層的field上設置一個列表數據的值。具體抽取規則如下:
fields: [ { name:"stocks", selector:"$.stocks", selectorType:SelectorType.JsonPath, repeated:true, children:[ { name:"code", alias:"代碼", selector:"$.code", selectorType:SelectorType.JsonPath, }, { name:"name", alias:"名稱", selector:"$.name", selectorType:SelectorType.JsonPath, }, { name:"current", alias:"當前價格", selector:"$.current", selectorType:SelectorType.JsonPath, }, { name:"high", alias:"最高價格", selector:"$.high", selectorType:SelectorType.JsonPath, }, { name:"low", alias:"最低價格", selector:"$.low", selectorType:SelectorType.JsonPath, } ] } ]
我簡單抽取了一些信息,其他信息都類似。
好了,主要的代碼基本已經寫好了,剩下的還需要解決兩個問題
1.爬取前需要先訪問一下首頁獲取cookie
2.雖然可以直接加入下一頁,但是一共有多少頁並不知道。
首先對於第一點,我們只需要在beforeCrawl回調中訪問一下首頁即可,神箭手會自動對cookie進行處理和保存,具體代碼如下:
configs.beforeCrawl =function(site){
site.requestUrl("http://xueqiu.com");
};
好了,除了下一頁基本已經沒什么問題了,我們先測試一下看看效果:

數據已經出來了,沒問題,第一頁的數據都有了,那下一頁怎么處理呢?我們有兩個方案:
第一個方案:
我們可以看到json的返回值中有一個count字段,這個字段目測應該是總數據量的值,那沒我們根據這個值,再加上單頁數據條數,我們就可以判斷總共有多少頁了。
第二個方案:
我們先訪問一下,假設頁數很大,看看會雪球會返回什么,我們嘗試訪問第500頁,可以看到返回值中的stocks是0個,那么我們可以根據是否有數據來判斷需不需要加下一頁。
兩個方案各有利弊,我們這里選擇用第一個方案來處理,具體代碼如下:
configs.onProcessHelperPage =function(page, content, site){ if(page.url.indexOf("page=1&size=30") !== -1){ //如果是第一頁 varresult = JSON.parse(page.raw); varcount = result.count.count; varpage_num = Math.ceil(count/30); if(page_num > 1){ for(vari = 2;i<=page_num;i++){ site.addUrl("http://xueqiu.com/stock/cata/stocklist.json?page="+i+"&size=30&order=desc&orderby=percent&type=11%2C12"); } } } };
好了,通過三課的艱苦奮戰,終於完成了雪球滬深一覽的征服。先看下跑出來的效果。

完整代碼如下:
varconfigs = { domains: ["xueqiu.com"], scanUrls: ["http://xueqiu.com/stock/cata/stocklist.json?page=1&size=30&order=desc&orderby=percent&type=11%2C12"], contentUrlRegexes: ["http://xueqiu.com/stock/cata/stocklist\\.json\\?page=\\d+&size=30&order=desc&orderby=percent&type=11%2C12"], helperUrlRegexes: ["http://xueqiu.com/stock/cata/stocklist\\.json\\?page=\\d+&size=30&order=desc&orderby=percent&type=11%2C12"], fields: [ { name:"stocks", selector:"$.stocks", selectorType:SelectorType.JsonPath, repeated:true, children:[ { name:"code", alias:"代碼", selector:"$.code", selectorType:SelectorType.JsonPath, }, { name:"name", alias:"名稱", selector:"$.name", selectorType:SelectorType.JsonPath, }, { name:"current", alias:"當前價格", selector:"$.current", selectorType:SelectorType.JsonPath, }, { name:"high", alias:"最高價格", selector:"$.high", selectorType:SelectorType.JsonPath, }, { name:"low", alias:"最低價格", selector:"$.low", selectorType:SelectorType.JsonPath, } ] } ] }; configs.onProcessHelperPage =function(page, content, site){ if(page.url.indexOf("page=1&size=30") !== -1){ //如果是第一頁 varresult = JSON.parse(page.raw); varcount = result.count.count; varpage_num = Math.ceil(count/30); if(page_num > 1){ for(vari = 2;i<=page_num;i++){ site.addUrl("http://xueqiu.com/stock/cata/stocklist.json?page="+i+"&size=30&order=desc&orderby=percent&type=11%2C12"); } } } }; configs.beforeCrawl =function(site){ site.requestUrl("http://xueqiu.com"); }; varcrawler =newCrawler(configs); crawler.start();
這樣我們的雪球網股票爬蟲就算大功告成,當然我們還可以把type的設置模板化。不過這個是一些高級的方法,我們會在后面的課程中再去詳細描述。
最后,對爬蟲感興趣的童鞋歡迎加qq群跟我討論:566855261。