tinyspider是一個基于tiny htmlparser的網絡資料抓取架構。
maven引用坐标:
<a href="http://my.oschina.net/tinyframework/blog/194610#">?</a>
1
2
3
4
5
<code><dependency></code>
<code><groupid>org.tinygroup</groupid></code>
<code><artifactid>tinyspider</artifactid></code>
<code><version></code><code>0.0</code><code>.</code><code>12</code><code></version></code>
<code></dependency></code>
網絡爬蟲,一般用在全文檢索或内容擷取上面。
tiny架構對此也做了有限的支援,雖然功能不多,但是想做全文檢索或從網頁上擷取資料也是非常友善的。
強大的節點過濾能力
支援post與get兩種資料送出方式
避免網頁重複處理功能
支援多站點内容抓取功能
較強的html容錯處理
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<code>public</code> <code>interface</code> <code>spinder {</code>
<code> </code><code>/**</code>
<code> </code><code>* 添加站點通路器</code>
<code> </code><code>*</code>
<code> </code><code>* @param sitevisitor</code>
<code> </code><code>*/</code>
<code> </code><code>void</code> <code>addsitevisitor(sitevisitor sitevisitor);</code>
<code> </code><code>* 添加螢幕</code>
<code> </code><code>* @param watcher</code>
<code> </code><code>void</code> <code>addwatcher(watcher watcher);</code>
<code> </code><code>* 處理url</code>
<code> </code><code>* @param url</code>
<code> </code><code>void</code> <code>processurl(string url);</code>
<code> </code><code>* @param parameter</code>
<code> </code><code>void</code> <code>processurl(string url, map<string, object> parameter);</code>
<code> </code><code>* 設定url倉庫</code>
<code> </code><code>* @param urlrepository</code>
<code> </code><code>void</code> <code>seturlrepository(urlrepository urlrepository);</code>
<code>}</code>
一個爬蟲,至少需要包含一個站點通路器,站點通路器用于對url進行通路。如果沒有比對的站點通路器,url将被忽略,不做繼續處理。
一個爬蟲至少需要包含一個螢幕,螢幕用于對url中的内容進行過濾,并對命中的節點進行處理。如果沒有螢幕,爬蟲爬回的内容就沒有任何價值。
一個爬蟲至少需要一個url倉庫,url倉庫用于對ur進行判斷,是否已經抓取并處理過。如果沒有url倉庫,将無法判斷url是否處理過,在非常多的時候,會造成死循環,無法退出。
當然,一個爬蟲,也必須能夠對url進行處理。
由于一個爬蟲可以有多個站點通路器,是以,需要有ismatch方法告訴爬蟲是否應該由自己進行處理。
通路方式,可以設定是通過get還是post方式擷取資料。
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<code>public</code> <code>interface</code> <code>urlrepository {</code>
<code> </code><code>* 傳回url是否已經在倉庫中存在</code>
<code> </code><code>* @return</code>
<code> </code><code>boolean</code> <code>isexist(string url);</code>
<code> </code><code>* 傳回url是否已經在倉庫中存在,帶有參數</code>
<code> </code><code>boolean</code> <code>isexist(string url, map<string, object> parameter);</code>
<code> </code><code>* 如果不存在,則放放,如果已經存在,則替換</code>
<code> </code><code>* @param content</code>
<code> </code><code>void</code> <code>puturlwithcontent(string url, string content);</code>
<code> </code><code>void</code> <code>puturlwithcontent(string url, map<string, object> parameter,</code>
<code> </code><code>string content);</code>
<code> </code><code>* 如果存在,則傳回内容;如果不存在,則抛出運作時異常</code>
<code> </code><code>string getcontent(string url);</code>
<code> </code><code>string getcontent(string url, map<string, object> parameter);</code>
url倉庫用于對url及其内容進行管理。由于方法都簡單明了,是以不做更多介紹。
<code>public</code> <code>interface</code> <code>watcher {</code>
<code> </code><code>* 設定節點過濾器</code>
<code> </code><code>* @param filter</code>
<code> </code><code>void</code> <code>setnodefilter(nodefilter<htmlnode> filter);</code>
<code> </code><code>* 擷取節點過濾器</code>
<code> </code><code>nodefilter<htmlnode> getnodefilter();</code>
<code> </code><code>* 添加處理器</code>
<code> </code><code>* @param processor</code>
<code> </code><code>void</code> <code>addprocessor(processor processor);</code>
<code> </code><code>* 擷取處理器清單</code>
<code> </code><code>list<processor> getprocessorlist();</code>
一個螢幕,必須一個節點過濾器,但是可以有多個處理器。
<code>public</code> <code>interface</code> <code>processor {</code>
<code> </code><code>* 處理節點</code>
<code> </code><code>* @param node</code>
<code> </code><code>void</code> <code>process(htmlnode node);</code>
處理器非常簡單, 就是對命中的節點進行處理即可。
下面我們就來編寫一段程式來把這些标題打出來:
<code>public</code> <code>static</code> <code>void</code> <code>main(string[] args) {</code>
<code> </code><code>spinder spinder =</code><code>new</code> <code>spinderimpl();</code>
<code> </code><code>watcher watcher =</code><code>new</code> <code>watcherimpl();</code>
<code> </code><code>watcher.addprocessor(</code><code>new</code> <code>printoschinaprocessor());</code>
<code> </code><code>quicknamefilter<htmlnode> nodefilter =</code><code>new</code> <code>quicknamefilter<htmlnode>();</code>
<code> </code><code>nodefilter.setnodename(</code><code>"div"</code><code>);</code>
<code> </code><code>nodefilter.setincludeattribute(</code><code>"class"</code><code>,</code><code>"qbody"</code><code>);</code>
<code> </code><code>watcher.setnodefilter(nodefilter);</code>
<code> </code><code>spinder.addwatcher(watcher);</code>
<code> </code><code>spinder.processurl(</code><code>"http://www.oschina.net/question?catalog=1"</code><code>);</code>
<code> </code><code>}</code>
<code>public</code> <code>class</code> <code>printoschinaprocessor</code><code>implements</code> <code>processor {</code>
<code> </code><code>public</code> <code>void</code> <code>process(htmlnode node) {</code>
<code> </code><code>fastnamefilter<htmlnode> filter =</code><code>new</code> <code>fastnamefilter<htmlnode>(node);</code>
<code> </code><code>filter.setnodename(</code><code>"h2"</code><code>);</code>
<code> </code><code>filter.setincludenode(</code><code>"a"</code><code>);</code>
<code> </code><code>htmlnode h3 = filter.findnode();</code>
<code> </code><code>if</code> <code>(h3 !=</code><code>null</code><code>) {</code>
<code> </code><code>system.out.println(h3.getsubnode(</code><code>"a"</code><code>).getcontent());</code>
輸出結果可能與結果不相同,因為資料是一直在變化的。
<code>約瑟夫環問題,一段代碼求講解</code>
<code>求推薦一款分享,回複的前端開源js</code>
<code>mysql什麼情況使用myisam,什麼時候使用innodb?</code>
<code>phpstorm中使用搜狗輸入中文出現亂行問題怎樣解決?</code>
<code>android中如何實作快播中娛樂風向标的效果</code>
<code>使用java做手機背景開發!</code>
<code>chrome</code><code>29</code><code>的alert對話框好漂亮,有木有啊有木有</code>
<code>eclipse+adt+android環境配置問題</code>
<code>關于android holderview的疑惑</code>
<code>蛋疼 從一個公司到另外一個公司都是一個人開發 有木有</code>
<code>wsunit 官方通路不了</code>
<code>android求大神給我看看什麼問題</code>
<code>關于hibernate search 查詢結果與資料庫不相符的問題</code>
<code>求推薦oracle好的書籍或pdf</code>
<code>關于</code><code>"記事本"</code><code>的</code><code>"自動換行"</code> <code>的實作</code>
<code>swing線上html文本編輯器</code>
<code>android下網絡阻塞問題</code>
<code>檔案上線系統該如何做(代碼上線)</code>
<code>ztree節點設定成check多選框的時候如何隻擷取葉節點,不要其他節點</code>
<code>怎麼設定上傳的圖檔不自動壓縮</code>
<code>js 正規表達式問題</code>
<code>eclipse 經常loading descriptor</code><code>for</code> <code>xxx ,然後卡死</code>
<code>關于android開發xml顯示問題</code>
<code>rmi遠端對象是共享的吧?</code>
<code>參與開源項目如何進行文檔編寫</code>
<code>php如何以檔案圖示的形式列出伺服器上的所有檔案?</code>
<code>php中一個簡單的問題?請幫助解決一下,菜鳥</code>
<code>請教 solr query分詞查詢,結果為空的問題</code>
<code>這段代碼有問題嗎,怎麼我運作報錯?</code>
<code>jquery mobile 頁面中切換閃屏問題</code>
<code>你幫我改好,我給你講個笑話可好tut</code>
<code>asp.net問題:js如何擷取cookie中的值?</code>
<code>android 電話攔截并處理</code>
<code>iis7 下 php 如何顯示報錯?</code>
<code>安裝virtualbox的時候提示要安裝通用串行總線控制器,這個要安裝嗎?</code>
<code>api擷取新浪微網誌消息</code>
<code>工廠該不該有預設行為</code>
<code>如何處理開發過程中遺留無用的代碼</code>
<code>ireport 設計時報表模闆時,無法使用sybase驅動com.sybase.jdbc3.jdbc.sybdriver?</code>
<code>關于 使用druid後的一些問題.</code>
從示例可以看出,要從網頁裡擷取資料,确實是非常容易的一件事情,隻寥寥幾行(20行左右),就采集出了我們想要的資料,要想抓出更多的資料,隻要逐層細化分析即可。