1. 程式人生 > >nutch主流程程式碼閱讀心得

nutch主流程程式碼閱讀心得

 

之前對nutch進行些分析,打算在基礎上進行一些應用,不過最近忙著,也沒弄出個所以然,先把閱讀心得貼出來,裡邊可能有不少理解上的錯誤,僅供參考用,萬一突然有人轉載了,請保留blog出處 。也希望能認識跟多對此話題感興趣的朋友。

主要類分析:
一、org.apache.nutch.crawl.Injector:
    1,注入url.txt
    2,url標準化
    3,攔截url,進行正則校驗(regex-urlfilter.txt)
    4,對符URL標準的url進行map對構造<url, CrawlDatum>,在構造過程中給CrawlDatum初始化得分,分數可影響url host的搜尋排序,和採集優先順序!
    5,reduce只做一件事,判斷url是不是在crawldb中已經存在,如果存在則直接讀取原來CrawlDatum,如果是新host,則把相應狀態儲存到裡邊(STATUS_DB_UNFETCHED(狀態意思為沒有采集過))

二、org.apache.nutch.crawl.Generator:


    1,過濾不及格url (使用url過濾外掛)
    2,檢測URL是否在有效更新時間裡
    3,獲取URL metaData,metaData記錄了url上次更新時間
    4,對url進行打分
    5,將url載入相應任務組(以host為分組)
    6,計算url hash值
    7,收集url, 直至到達 topN 指定量

三、org.apache.nutch.crawl.Fetcher:
    1,從segment中讀取<url, CrawlDatum>,將它放入相應的佇列中,佇列以queueId為分類,而queueId是由 協議://ip 組成,在放入佇列過程中,
        如果不存在佇列則建立(比如javaeye的所有地址都屬於這個佇列:http://221.130.184.141)  --> queues.addFetchItem(url, datum);
    2,檢查機器人協議是否允許該url被爬行(robots.txt) --> protocol.getRobotRules(fit.url, fit.datum);
    3,檢查url是否在有效的更新時間裡 --> if (rules.getCrawlDelay() > 0)
    4,針對不同協議採用不同的協議採用不同機器人,可以是http、ftp、file,這地方已經將內容儲存下來(Content)。 --> protocol.getProtocolOutput(fit.url, fit.datum);
    5,成功取回Content後,在次對HTTP狀態進行識別(如200、404)。--> case ProtocolStatus.SUCCESS:
    6,內容成功儲存,進入ProtocolStatus.SUCCESS區域,在這區域裡,系統對輸出內容進行構造。 --> output(fit.url, fit.datum, content, status, CrawlDatum.STATUS_FETCH_SUCCESS);
    7,在內容構造過程中,調取內容解析器外掛(parseUtil),如mp3\html\pdf\word\zip\jsp\swf……。 --> this.parseUtil.parse(content); --> parsers[i].getParse(content);
    8,我們現在研究html解析,所以只簡略說明HtmlParser,HtmlParser中,會解析出text,title, outlinks, metadata。 
        text:過濾所有HTML元素;title:網頁標題;outlinks:url下的所有連結;metadata:這東西分別做那麼幾件事情 首先檢測url頭部的meta name="robots" 看看是否允許蜘蛛爬行,
        其次通過對meta http-equiv
refresh等屬性進行識別記錄,看頁面是否需要轉向。

四、org.apache.nutch.parse.ParseSegment:
    1,這個類邏輯就相對簡單很多了哦,它對我們也是很有價值的,它只做一件事情,就是對爬行下來的Content(原始HTML)進行解析,具體解析通過外掛來實現。
        比如我們要做的資料分析、資料統計都可以在這進行實現。
    2,執行完成後,輸出三個Map對<url,ParseText>解析內容、<url,ParseData>包含所有連結的分析後的結果 、<url,CrawlDatum>outlinks

五、org.apache.nutch.crawl.CrawlDb:

    主要根據crawld_fatch輸出更新crawldb。
    1,map對crawld_fatch、crawldb地址進行標準化(nomalizer)和攔截操作(filte);
    2,reduce在對兩crawld_fatch和crawldb進行合併更新。

六、org.apache.nutch.crawl.LinkDb:
    這個類的作用是管理新轉化進來的連結對映,並列出每個url的外部連結(incoming links)。
    1,先是對每一個url取出它的outLinks,作map操作把這個url作為每個outLinks的incoming link,
    2,在reduce裡把根據每個key來把一個url的所有incoming link都加到inlinks裡。
    3,這樣就把每個url的外部連結統計出來了,注意,系統對只對外部連結進行統計,什麼叫外部連結呢,就是隻對不同host進行統計,
        記住iteye.com和biaowen.iteye.com是兩個不同的host哦。 --> boolean ignoreInternalLinks = true;
    4,然後一步是對這些新加進來的連結進行合併。

七、org.apache.nutch.crawl.Indexer:
    這個類的任務是另一方面的工作了,它是基於hadoop和lucene的分散式索引。它就是為前面爬蟲抓取回來的資料進行索引好讓使用者可以搜尋到這些資料。
    這裡的輸入就比較多了,有segments下的fetch_dir,parseData和parseText,還有crawldb下的 current_dir和linkdb下的current_dir。
    1,在這個類裡,map將所有輸入都裝載到一個容器裡邊,
    2,在到reduce進行分類處理,
    3,實現攔截 --> this.filters.filter(doc, parse, key, fetchDatum, inlinks);
    4,打分 --> this.scfilters.indexerScore(key, doc, dbDatum,fetchDatum, parse, inlinks, boost);
    5,當然要把這些資料體組合成一個 lucene的document讓它索引了。
    6,在reduce裡組裝好後收集時是<url,doc>,最後在輸出的OutputFormat類裡進行真正的索引。
        doc裡有如下幾個field
            content(正文)
            site    (所屬主地址)
            title    (標題)
            host    (host)
            segement    (屬於哪個segement)
            digest    (MD5碼,去重時候用到)
            tstamp    (暫時不知道什麼東西)
            url    (當前URL地址)
            載了一個例子:
                doc =
                    {content=[biaowen - JavaEye技術網站 首頁 新聞 論壇 部落格 招聘 更多 ▼ 問答 ………………(內容省略)………… biaowen 永NF/ICP備05023328號],
                    site=[biaowen.iteye.com],
                    title=[biaowen - JavaEye技術網站],
                    host=[biaowen.iteye.com],
                    segment=[20090725083125],
                    digest=[063ba8430fa84e614ce71276e176f4ce],
                    tstamp=[20090725003318265],
                    url=[http://biaowen.iteye.com/]}

八、org.apache.nutch.crawl.DeleteDuplicates:
    這個類的作用就是這它的名字所寫的意思--去重。
    前面索引後(當然不是一次時的情況)會有重複,所以要去重。為什麼呢,在一次索引時是不重複的,可是多次抓取後就會有重複了。
    就是這個原因才要去重。當然去重的規則有兩種一個是以時間為標準,一種是以內容的md5值為標準。

九、org.apache.nutch.indexer.IndexMerger:
    這個類就相對簡單了,目的將多個indexes合併為一個index,直接呼叫lucene方法實現!


附帶些參考資料:

目錄結構,參考自《Lucene+Nutch搜尋引擎開發》
    一、crawldb    下載的url,以及下載日期,用來進行頁面更新
    二、segements    存放抓取頁面和分析結果
                        1、crawl_generate:待下載url
                        2、crawl_fetch:每個下載url的狀態
                        3、content:每個下載頁面的內容
                        4、parse_text:包含每個解析過的url文字內容
                        5、parse_data:每個url解析出的外部連結和元資料
                        6、crawl_parse:用來更新crawl的外部連結庫
    三、linkdb    存放url的互聯關係
    四、indexes:存放每次下載的獨立索引目錄
    五、index:符合lucene格式的索引目錄,是indexes裡所有index合併後的完整索引