首頁>技術>

【摘要】 集算器 SPL 支援抓取網頁資料,根據抓取定義規則,可將網頁資料下載到在本地進行統計分析。具體定義規則要求、使用詳細情況,請前往乾學院:集算器 SPL 抓取網頁資料!

1、基本流程圖2、抓取網頁資料介面3、定義規則 A、web_info B、init_url C、help_url D、target_url E、page_url4、抓取股票歷史資料5、使用者自定義程式 A、資料提取程式介面 B.資料儲存程式介面 C、資料提取程式樣例 D、資料儲存程式樣例 E、自定義程式的使用

1、基本流程圖

從給定的開始地址進行遍歷,將解析過濾後的網址放入下載地址佇列,分成網址頁 help_url 與下載頁 target_url, 網址頁只收集網址,下載頁即能收集網址,也能提取資料,把提取到的資料儲存起來。抓取網頁資料直到遍歷地址為空,則抓取工作結束。

2、抓取網頁資料介面 web_crawl(jsonstr) 是抓取網頁資料介面,引數 jsonstr 是定義規則的字串,抓取資料時,根據定義規則遍歷 URL、下載、提取、儲存相關內容資料。 本介面依賴集算器外部庫 webcrawlCli。它預設安裝在集算器軟體的 esProc\extlib\webcrawlCli 路徑下,在集算器的外部庫設定中勾選 webcrawlCli 項, 重啟集算器後,就可以使用 web_crawl 介面。

web_crawl 簡單用法,如抓取指定股票資料,SPL 指令碼 demo.dfx:

獲取股票程式碼 600000 的資料檔案:

檔案內容:

3、定義規則根據基本流程圖,將定義規則分成網站資訊、初始網址、網址頁、下載頁、提取資料五部分。具體內容如下:[{web_info:{domain:‘www.banban.cn’, save_path:‘d:/tmp/data/webmagic’, thread_size:2, cookie:{name:“jacker”, laster:“2011”},user_agent:‘Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:39.0) Gecko/20100101 Firefox/39.0’}},{init_url:[‘_cybs.htmlhttps://www.banban.cn/gupiao/list’, ‘_sh.htmlhttps://www.banban.cn/gupiao/list’]},{help_url:[‘gupiao/list_(sh|sz|cyb)\.html’, ‘/shujv/zhangting/’, ‘/agu/$’]},{target_url:{reg_url:‘/agu/365\d’}},{target_url:{filter:‘gupiao/list_(sh|sz|cyb)\.html’, reg_url:‘gupiao/[sz|sh]?(60000\d)/’,new_url:‘http://www.aigaogao.com/tools/history.html?s=%s’}},{page_url:{filter:‘history.html\?s=\d{6}’, extractby: “//div[@id=‘ctl16_contentdiv’]/”}},{page_url:{extractby: “//div[@id=‘content_all’]/”}},{page_url:{filter:‘/agu/365\d’, extractby: “//div[@id=‘content’]/”}}]

規則簡要說明:web_info:網站資訊, 根據要下載的網站,設定域名、本地儲存位置、使用者代理資訊、使用者自定義程式等相關的資訊。init_url:初始網址, URL 遍歷的入口網址。help_url:網址頁, 定義網址頁規則,收集網頁內容中的 URL,但不提取此頁面資料內容。target_url:下載頁, 定義下載頁規則,收集網頁內容中的 URL,同時也提取此頁面的內容。page_url:提取資料, 定義頁面內容提取規則,在下載頁 target_url 中根據此規則提取內容。

注意: json 書寫結構細節,節點 {} 中的 [] 表示 list 列表,節點 {} 中的 {} 表示 map 鍵值結構,書定時要注意,否則書寫不對易引起解析錯誤。

定義規則說明

A、web_info設定要下載的資訊,內容包括:domain:設定域名。save_path:檔案儲存路徑。user_agent:指使用者代理資訊。 作用: 使伺服器能夠識別客戶使用的作業系統及版本、CPU 型別、瀏覽器及版本、瀏覽器渲染引擎、瀏覽器語言、瀏覽器外掛等。sleep_time:抓取間隔。cycle_retry_times:重試次數。charset:設定編碼。use_gzip:是否為 gzip 壓縮。time_out:抓取超時設定。cookie_name:cookie 資訊,鍵值結構。thread_size:抓取時執行緒數。save_post:是否要為儲存的檔名稱追加編碼串,以防網名檔案被覆蓋,預設值為 true。如 books/a.html, music/a.html, 都是要下載的頁面,儲存時若此引數為 true, 則儲存檔名分別為 a_xxxcgk.txt,a_xabcdw.txt,檔案不會被覆蓋;若為 false, 儲存檔名為 a.txt, 後儲存的就會將已存在的同名檔案覆蓋。class_name:使用者自定義的儲存類。class_argv:傳遞給 class_name 類的字串引數。

B、init_url初始的 URL。為 List 列表結構,可設定多個 URL.

C、help_url網址頁主要是定義要收集的 URL 過濾規則, 符合規則的 URL 會被加入下載網址佇列,但是不會提取其具體內容。過濾規則支援正則表示式,如:gupiao/list_(sh|sz|cyb)\.html 表示 URL 中只有包括字串 gupiao/list_sh.html、gupiao/list_sz.html、gupiao/list_cyb.html 連結才能透過。為 List 列表結構,可定義多個規則。

D、target_url下載頁是要抓取內容資料的 URL,需要從這個頁面裡提取內容。若此 URL 符合 help_url 過濾規則,那麼也會在本頁面中收集 URL。約定定義規則格式:{target_url:{filter: pageUrl, reg_url:urlRegex, new_url:newUrl}},表示在符合 pageUrl 條件的頁面中,找出符合 urlRegex 條件的 href 連結,若 newUrl 定義了,則可與 urlRegex 過濾結果組合成新的 URL。例如在頁面中找到連結 a_100.html 符合過濾條件 reg_url=a_(\d+)\.html, 則有 newUrl=b_%s.php, 那麼 urlRegex 過濾 a_100.html 的結果為 100, 將與 newUrl 合併,新的下載頁為 b_100.php。其中 filter 表示定義過濾的 URL 規則;若無此定義,表示所有的 target_url 都要用此規則。reg_url 表示要收集的 URL 規則,必寫;無 reg_url 的 target_url 規則則無意義。new_url 表示定義新的頁面,需要與 reg_url 過濾結果結合成新的 URL。

舉例說明:3.1 定義規則:{target_url:{filter:‘gupiao/list_(sh|sz|cyb)\.html’, reg_url:‘gupiao/([sz|sh]?6000\d{2})/’,new_url:‘http://www.raqsft.com/history.html?s=%s’}}在下載頁 gupiao/list_sh.html 中包含如下內容:

包鋼股份 (600010)四川路橋 (600039)保利地產 (600048)

A、gupiao/list_sh.html 符合 filter 條件B、href 串符合 reg_url 條件,將產生 [600010, 600039, 600048]C、過濾結果與 newUrl 生成新的 URL:http://www.raqsft.com/history.html?s=600010http://www.raqsft.com/history.html?s=600039http://www.raqsft.com/history.html?s=600048new_url 中的 %s 為合併字串的佔位符。

3.2 定義規則:{target_url:{reg_url:‘/ gupiao/60001\d’}},

在下載頁 gupiao/list.html 中包含如下內容:

包鋼股份 (600010)四川路橋 (600039)保利地產 (600048)

href 中符合 reg_url 條件的,則收集到的 URL 為: http://www.xxx.com/gupiao/600010/ 其它兩個 href 不符合過濾條件。 設定 filter 是為了在過濾後的頁面中去收集 URL, 當 help_url 多時,過濾後縮小了範圍,提高了效率。 target_url 規則可定義多條,以適應不同的條件。

E、page_url提取資料,主要作用於下載頁面內容提取,它表示使用這個抽取規則,將提取到的結果儲存。定義此規則參考 xpath 使用說明。它只提取主要內容,但對內容細節還需要 className 類來抽取。約定定義規則格式:{page_url:{filter: pageUrl, extractby: contentReg, class: className }},其中 filter 表示符合過濾條件的 url 規則,若無此定義,表示所有的 target_url 都要用此規則。extractby 表示頁面內容提取規則。若定義 class,表示由 className 類執行內容提取;若 className=”default”, 表示用當前預設方式提取,也就是針對 table 表中的內容提取資料。若預設提取不滿足需求,使用者可自定義類來實現,具體實現參考後面使用者自定義程式。例如:extractby :“//div[@class=news-content]/text()”,從網頁中提取此節點下的資料。

page_url 可針對不同的頁面制定不同的規則。透過 filter 過濾後的頁面中去提取資料,減少要處理的 URL 數量,當 target_url 多時,能提高效率。

若無 extractby 規則,則表示提取 target_url 頁面中所有的內容。若定義了多條 page_url 規則 ,則首個符合規則的內容將被提取。假如 A 頁面內容的符合規則 R1,R2,R3, 提取內容時首先是 R2,則不再根據 R1、R3 規則提取資料。說明:若沒有定義 target_url 規則,但當前頁面有適合的 page_url 規則,則此頁面的內容也會被提取。

4、抓取股票歷史資料

下面用抓取股票歷史資料來說明,web_crawl() 介面是如何應用的。基本操作:先獲取股票程式碼,然後透過股票程式碼查詢歷史資料,從下載頁面中提取資料後儲存。A、在https://www.banban.cn/gupiao/list_xxx.html 頁面 help_url 提取上證、深證、創業板的股票程式碼。B 、將股票程式碼與http://www.aigaogao.com/tools/history.html?s=%s 結合,生成需要下載網址 target_url.C 、針對下載頁 target_url 中的內容提取。

D、顯示提取後的內容。

SPL 實現程式碼 Stock.dfx:

載入其中的股票 600010 資料為:

5、使用者自定義程式 對於內容提取,預設提供了對 html 中的 table 內容進行抽取。 但是世界上沒有千篇一律的網頁一樣,也沒有一勞永逸的提取演算法。在使用網頁資料抓取過程中,你會碰到各種型別的網頁,這個時候,你就要針對這些網頁,來實現對應抽取方法。儲存方式類似,預設提供的是檔案儲存,若想其它方式如資料庫儲存,還需要使用者自己開發程式。參考下面介面,可將自定義程式融入網頁資料抓取流程中。

A、資料提取程式介面

下載頁的內容組織形式多樣,各具不同,為了適應更多的內容提取需求,使用者可自定義提取資料程式。介面程式:package com.web;

import us.codecraft.webmagic.Page;public interface StandPageItem {// 資料提取處理。void parse(Page p);}

需要實現 com.web.StandPageItem 介面 parse(Page p),資料提取在此實現。

B、資料儲存程式介面提取資料儲存方式種類繁多,各具不同,為了適應更多的資料儲存需求,使用者可自定義資料儲存程式。介面程式:package com.web;import us.codecraft.webmagic.ResultItems;import us.codecraft.webmagic.Task;import us.codecraft.webmagic.pipeline.Pipeline;

public interface StandPipeline extends Pipeline { public void setArgv(String argv); public void process(ResultItems paramResultItems, Task paramTask);}同樣需要實現 com.web.StandPipeline 類中的 setArgv(), process()。setArgv()輸入引數介面,process() 處理儲存資料介面。

C、資料提取程式樣例實現 com.web.StandPage 介面 parse(Page p),參考程式碼:package com.web;import java.util.List;import us.codecraft.webmagic.Page;import us.codecraft.webmagic.selector.Selectable;

public class StockHistoryData implements StandPageItem{ @Override public void parse(Page page) { StringBuilder buf = new StringBuilder(); List nodes = page.getHtml().xpath(“table/tbody/”).nodes(); for(Selectable node:nodes){ String day = node.xpath(“//a/text()”).get(); List title = node.xpath(“//a/text() | tr/td/text()”).all(); if (title.size()<5) continue; String line = title.toString().replaceFirst(“, ,”, “,”); buf.append(line+“\n”); } page.putField(“content”, buf.toString()); }}

將要儲存的資料存放到 page 的欄位 "content" 中,在儲存處理時,將從欄位 "content" 中獲取。

D、資料儲存程式樣例實現 com.web.StandPageline 類中的 setArgv(),process()參考程式碼:package com.web;import java.io.File;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import us.codecraft.webmagic.ResultItems;import us.codecraft.webmagic.Task;import org.apache.commons.codec.digest.DigestUtils;import us.codecraft.webmagic.utils.FilePersistentBase;public class StockPipeline extends FilePersistentBase implements StandPipeline { private Logger logger = LoggerFactory.getLogger(getClass()); private String m_argv; private String m_path; public static String PATH_SEPERATOR = “/”; static { String property = System.getProperties().getProperty(“file.separator”); if (property != null) { PATH_SEPERATOR = property; } } public StockPipeline() { m_path = “/data/webcrawl”; } // 獲取儲存路徑與儲存檔名字首 public void setArgv(String argv) { m_argv = argv; if (m_argv.indexOf(“save_path=”)>=0){ String[] ss = m_argv.split(“,”); m_path = ss[0].replace(“save_path=”, ““); m_argv = ss[1]; } } public void process(ResultItems resultItems, Task task) { String saveFile = null; Object o = null; String path = this.m_path + PATH_SEPERATOR + task.getUUID() + PATH_SEPERATOR; try { do{ String url = resultItems.getRequest().getUrl(); o = resultItems.get(“content”); if (o == null){ break; } int start = url.lastIndexOf(”/”); int end = url.lastIndexOf(“?”); if (end<0){ end=url.length(); } String link = url.substring(start+1, end); if (m_argv!=null && !m_argv.isEmpty()){ link = m_argv+“_”+link; } if (link.indexOf(“.”)>=0){ link = link.replace(“.”, “_”); } // 加 md5Hex 為防止重名 String hex = DigestUtils.md5Hex(resultItems.getRequest().getUrl()); saveFile = path + link+“_”+ hex +“.json”; }while(false); if (saveFile!=null){ PrintWriter printWriter = new PrintWriter(new FileWriter(getFile(saveFile))); printWriter.write(o.toString()); printWriter.close(); } } catch (IOException e) { logger.warn(“write file error”, e); } }}

E、自定義程式的使用 將上述介面檔案及 java 檔案編譯後打包成 webStock.jar 檔案,放在 esProc\extlib\webcrawlCli 路徑下重啟集算器。資料儲存程式,在 web_info 中配置;資料提取程式,在 page_url 中配置。下面是載入兩個自定義類程式的 dfx 指令碼。SPL 程式碼指令碼 mytest.dfx:

生成結果:

類似針對內容提取或資料儲存,參考上面程式的實現,使用者可自定義 java 程式。

15
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 排查指南 | mPaaS 小程式被卡在了三個藍點