◆曾 凱
(天津市醫藥科學研究所聯合辦 天津 300020)
醫藥科研信息網絡抓取方法研究
◆曾 凱
(天津市醫藥科學研究所聯合辦 天津 300020)
本文介紹了醫藥科研信息抓取系統中用到的數據抓取方法。為了高效地抓取網頁內容,該方法采用帶偏好的寬度優先遍歷方式訪問網頁,將待訪問的網址存放于高效的內存數據庫BerKeley DB中,用布隆過濾器過濾已經抓取過的網址。通過Delphi xe7開發系統提供的WebBrowser控件和微軟公司的MSHTML組件獲取網頁文本,將待提取數據文本劃分成數據行,將數據行及相應的鏈接存入到對象數組中,用關鍵字在對象數組中匹配搜索時可實現精確和模糊搜索兩種方式。并利用計算機的多線程技術提高網頁抓取速度,利用多核優勢帶來的并行編程技術提高對網頁內容中關鍵字的搜索速度。以萬方醫學網和中國知網為實際案例,闡述了數據抓取過程及結果,并提供了簡化的Delphi xe7示例程序,結果表明,該方法能有效方便地應用于醫藥科研信息的采集。
網頁內容識別;數據采集;寬度優先遍歷算法;內存數據庫;布隆過濾器;多線程技術;多核并行編程技術
在醫藥領域中從事科研工作,經常需要從互聯網上獲取大量的醫學及醫藥方面的信息,服務科研工作。這些信息涉及范圍廣、更新快,需要科研人員經常從眾多的網站中查找,費時費力。如果借助計算機技術,根據他們提供的關鍵詞在其關注的科研網站上自動搜尋相關信息,自動抓取數據,存入數據庫,進行加工處理,成為服務醫藥科研工作的“數據平臺”,為醫藥科研領域實施科學管理和科學研究提供重要的信息資源,就可以為科研工作者分析、利用信息資源進行科學管理、決策和開展大規模、高水平醫藥研究提供了有力的技術工具。如Butler,Leone,willenborg[1],以及Antweiler與Frank[2]等都利用互聯網網頁抓取技術獲取數據,很好地服務于研究工作。本文詳細闡述網頁內容抓取的實現技術、驗證窗口自動登錄的方法和先進的并行編程技術,以詳實的編程代碼展示實現方法,該方法能簡單、方便地獲取網上信息資源。此外,簡要介紹帶偏好的寬度優先遍歷算法、布隆過濾器的工作原理、內存數據庫的優勢及多線程爬蟲的結構。
互聯網數據采集是指利用互聯網搜索引擎技術實現有針對性、行業性、精準性的數據抓取,并按照一定規則和篩選標準進行數據歸類,并形成數據庫文件的一個過程[3]。互聯網擁有海量的數據,每日更新得非常快。網頁一般由文本、圖片、Flash動畫、表格、聲音等元素組成。網頁數據具有分布廣、格式多樣、非完全結構化或半結構化等大數據的典型特點。因此,在定位和訪問網頁內某數據項時,需根據網頁各元素的特征進行,可通過采集者的分析指引靈活進行[4-5]。數據抓取過程一般包括以下幾個步驟:
(1)確定抓取目標網址。先進入關注的網站,找到含有所需數據的網頁,判斷數據的準確性及抓取的難易程度,避免應用了防采集措施的網站。
(2)仔細分析頁面內容及其組織方式,確定抓取規則。由于網頁含有的元素和特性的數量十分巨大,除文字信息外,還有大量的頁面元素和其它多媒體數據。抓取前須了解網頁元素特點,確定所尋找的數據在網頁源文件代碼中的識別規則。可根據網頁源文件代碼進行分析。規則是:網址規則;網頁各元素的識別規則;數據行。
(3)借助數據抓取軟件或編程,依據規則抓取數據。
對網站的遍歷采用的是帶偏好的寬度優先遍歷方式。
對網站的遍歷可分為寬度優先和深度優先遍歷兩種方式。深度優先遍歷在深度遍歷子網頁時容易陷入“黑洞”。所以本系統采用帶偏好的寬度優先遍歷。寬度優先遍歷(BFS)算法是用分層搜索的方式遍歷網頁,將網站首頁作為起始點,采用層次遍歷的方式,逐層訪問網頁[6]。帶偏好的寬度優先遍歷算法比傳統的寬度優先遍歷算法有更高的效率。在訪問同一層的網頁時,把重要網頁的 URL鏈接地址從隊列中“挑”出來優先抓取該網頁內容。為了判斷該網頁是否重要,需要用到鏈接分析方法。本系統采用的是Google使用的PageRank算法,該算法并不是簡單地根據指向網頁的鏈接總數來計算,而是采用了運算法則:
PR(A)=(1-d)+d(PR(T1)/C(T1)+…+PR(Tn)/C(Tn))。
PR(A):網頁A的PageRank值;
PR(Ti):鏈接到A的Ti網頁的PageRank值;
C(Ti):網頁Ti的出站鏈接數量;
d:阻尼系數,0 由于本系統訪問的網站擁有數量巨大的網頁,所以為獲得網頁的重要性PR(A),使用了近似的計算方法來計算。即給每個網頁一個初始值,例如:PR(A)為1,再按照PageRank算法,循環進行有限次運算,得到近似的PR(A)值。 本系統網絡爬蟲使用最關鍵的數據結構是非常流行的內存數據庫,即Berkeley DB。 網絡爬蟲要訪問的網頁鏈接地址通常存放于隊列中,即內存數據結構。當面臨的網頁鏈接可能成千上萬時,內存數據結構就不適合這些應用了。而本系統使用的內存數據庫Berkeley DB可以解決該問題[7-8]。它能存儲大量數據,當數據超出內存容量時,能把它存儲在硬盤上;存取數據速度非常快;能夠支持多線程訪問[9-10]。 在網絡爬蟲訪問網頁時,為了判斷該網址是否訪問過,需將該網址與 Visited表(即存放訪問過的網址)中的網址做比較,如果存在,說明訪問過了,就跳過該網址。計算機中的集合Visited表采用哈希表的方式存放。優點是快速,缺點是占用較多的存儲空間。如果哈希表巨大,它存儲效率低的問題就突顯了。而布隆過濾器只需哈希表1/8至1/4的大小就能解決問題[11]。 布隆過濾器是一個很長的二進制向量和一系列隨機映射函數。工作原理是,假定Visited表里存儲了2億個網址,先建立一個20億二進制常量,它們的初始值為0。對于每個網址,用8個不同隨機數產生器產生8個信息指紋(f1,f2,…,f8)。再用一個隨機數產生器G把這8個信息指紋映射到20億中的8個二進制位中g1,g2,…,g8。這8個二進制位全部設置為1。所有網址都按此算法存放,節省存儲空間的布隆過濾器就建立好了。 布隆過濾器如何判斷某網址是否訪問過?用8個隨機數產生器(F1,F2,…,F8)對這個網址產生8個信息指紋,然后將這8個指紋對應到布隆過濾器的8個二進制位,分別是T1,T2,…,T8。如果網址在Visited表中,則T1,T2,…,T8對應的8個二進制位一定是1。 布隆過濾器的不足之處是它有極小的可能將一個未訪問過的網址判斷為已訪問過了。因為有可能某個網址正巧對應8個都被設置成1的二進制位。不過這種出錯的概率為萬分之一以下。可以建立一個名單,存儲容易誤判的網址[12]。 采用多線程并行抓取能同時獲得同一個網站的多個網頁,能極大地減少抓取網站的時間[13-15]。Delphi中有一個線程類TThread是用來實現多線程編程的。多線程爬蟲的結構見圖1。 醫藥科研人員將需要搜索的信息作為關鍵字存入關鍵字數據庫中。將他們平常關注的網站的網址存入網址數據庫中。如果需關注的網站有用戶身份驗證需求,就需要將用戶名和密碼事先存入數據庫中,以便自動登錄完成驗證。網頁搜索方式可設定為當前網頁搜索和子網頁搜索。準備工作做好后,操作時選擇關注的網址、需搜索的關鍵字和網頁搜索方式,點擊開始。系統會依次進入各網站,進入到網站后獲取網頁,提取文本,搜索關鍵字,如果找到了,將關鍵字所在的語句和相關的鏈接存入數據庫中。顯示查看結果時,在界面左則中選擇感興趣的關鍵字,右則窗口上半部顯示含有該關鍵字的多個標題,點擊某個標題,右則下半部就顯示該標題所在的網頁。結果見圖2。 圖2 顯示搜索結果 自動輸入用戶名和密碼,實現網頁的自動登錄。 在訪問含論文及綜述類信息資源的網站時,如天津圖書館電子網站、中國知網等,這類網站往往需要用戶名及密碼。本系統可以找到輸入框,將存入數據庫中的用戶名及密碼分別帶入到輸入框中,完成自動登錄。代碼如下: WebBrowser1.OleObject.document.all.item( “username”,0).value:=’0001’//找到用戶名的輸入框,輸入用戶名 WebBrowser1.OleObject.document.all.item( “password”,0).value:=’AAAA’//找到密碼的輸入框,輸入密碼 目前網站開發技術很多,網頁格式因此各不相同,如流行的格式有html、xml、asp、jsp等,但無論如何,它們都是通過HTTP協議將數據傳輸到客戶瀏覽器的。 獲取網頁源文件內容的過程是,先實現對網頁的下載,再解析網頁。本系統在 Delphi xe7應用程序開發環境中調用WebBrowser 控件實現網頁信息的獲取功能,達到下載目的。通過 WebBrowser 控件的 Document文檔接口對象實現對網頁的解析,方法簡單實用,分以下幾個步驟:(1)創建WebBrowser 控件;(2)通過控件方法Navigate連接到指定的網址;(3)通過控件屬性Document獲取對控件內顯示網頁的訪問途徑。(4)通過as將 WebBrowser.Document轉換為 Ihtmldocument2接口類型,用Ihtmldocument2接口訪問網頁Html的源文件文本。因為MSHTML是微軟公司的一個COM組件,該組件封裝了HTML語言中的所有元素及其屬性,通過其提供的標準接口,可以訪問指定網頁的所有元素.Ihtmldocument2接口是 MSHTML里的一個對象,用Ihtmldocument2的InnerHTML屬性可以獲得網頁源文件內容。 例如,下述為基于Delphi用于讀取網頁源文件的部分代碼。它返回指定網頁源文件文本。 WebBrowser1.Navigate(Trim(Edit4.Text));//用 WebBrowser控件打開網頁,Edit4.Text指定網址 str_html:=(webBrowser1.Document as IHtmlDocument2).Body.innerHTML;//將網頁內容存入str_html字符串變量中。 通過查找關鍵字,判斷網頁中是否含有所需要的內容,有兩種方法可以實現。(1)采用正則表達式,搜索關鍵字。優點:善于捕獲字符串,尤其是匹配url,email這種純文本的字符。缺點:只適合匹配文本字面,不適合匹配文本意義;貪婪匹配符號很容易造成大量的回溯,性能有時候會有上百萬倍的下降;正則的替換功能較差:甚至沒有基本的截取字符串或者把首字母改變大小寫的功能。該方法用于在不常用的網站中搜索內容。(2)通過自編的代碼實現類似的功能,在特定的環境中具有針對性、實用性和靈活性。該方法用于在常用的網站中搜索內容。 (1)為了采用正則表達式,在Delphi中使用第三方正則組件PerlRegEx。 部分代碼: Uses PerlRegEx; ……… RegEx := TPerlRegEx; Try RegEx.Subject := str_html;// str_html 存放網頁源文件內容。 RegEx.RegEx :=’分子靶向|兒童食道|結直腸腫瘤’; if RegEx.Match then .... finally RegEx.free end; 有時想獲取網頁中符合特定格式的鏈接,用正則表達式實現的效果最好。 圖1 多線程爬蟲的結構 想捕獲的鏈接是“ ” 正則表達式為:<[aA] s+ [hH] [rR] [eE] [fF]=s*(“|’)?(.*)(1)(s[^>]*)*?>(.*?)< /[aA]> (2)通過自編的代碼實現類似的功能。從源文件內容中去除代碼,提取文字內容。 例如為了從醫學文獻網站上搜尋相關的信息,就要在獲取源文件內容后,對數據進行提取并解析。源文件代碼中經常會包含、、、等標簽,文字內容會顯示在一對標簽的中間,如。“兒童食道異物的治療策略”是帶有鏈接的文本,該文本的前面有一個標識是“>”,可以作為執行提取文本操作的開始標識,后面有一個“<”,可作為結束標識。獲得文本后,還需要獲得相關鏈接。該文本前面的“href="”可作為鏈接地址的開始標識,鏈接地址后面的“"”可作為鏈接地址的結束標識,從而提取完整的鏈接地址。將文本和鏈接地址分別存入到對象數組中,以便查尋結果時使用。見圖3,圖4。 圖3 萬方醫學網首頁 圖4 首頁部分源代碼 聲名類TKey_Link,存放文本和鏈接地址 TKey_Link=class(Tpersistent) public Fkey:string; 存放文本 FLink:string; 存放該文本的鏈接地址 end; 用函數 GetKey_Link提取文本和鏈接地址,存入對象數組FGroupKey_Link中。該函數用到了pos函數,pos的功能是得到子串在父串中第一次出現的位置,用pos分別獲得開始標識“>”和結束標識“<”的位置,這兩個位置中間的內容就是文本內容。代碼如下: Function TForm1.GetKey_Link(webBrowser:TwebBrowser) :TObjectList; var …… FGroupKey_Link:TObjectList; //定義對象數組 FKey_Link:TKey_Link; begin FGroupKey_Link:=TObjectList.Create;//定義對象數組 str_html:=(webBrowser.Document as IHtmlDocument2).Body.innerHTML;//將網頁源文件內容存入str_html字符串變量中。 p1:=pos('>',str_html);//獲得開始標識的位置 while (p1>0) do begin str_front:=copy(str_html,1,p1);//獲得開始標識之前的內容,含標識符 str_html:=copy(str_html,p1+1,length(str_html)-p1);獲得開始標識之后的內容 if (copy(str_html,1,4)='',str_html); str_html:=copy(str_html,p5+Length('-->'),Length(str_html)-(p5+Length('-->')-1)); end; p2:=pos('<',str_html);獲得結束標識的位置 str_chart:=trim(copy(str_html,1,p2-1));截取兩標識之間的文本內容 if (length(str_chart)>0) then begin FKey_Link:=Tkey_Link.Create; strPress:=''; for j:=1 to Length(str_chart) do strPress:=strPress+trim(copy(str_chart,j,1)); str_chart:=strPress; FKey_Link.Fkey:=str_chart;將截取的文本內容存入對象的屬性Fkey中。 str_Link:=''; p3:=pos('href="',str_front);//該文本如果含鏈接地址,就將地址存入str_Link中 if(p3>0) then begin str_front:=copy(str_front,p3+Length('href="'),Length(str_front)-(p 3+Length('href="'))+1); p4:=pos('"',str_front); if (p4>0) then begin str_Link:=copy(str_front,1,p4-1); end; end; if (Length(trim(str_Link))>0) then begin ……去掉地址中無用的字符。 FKey_Link.FLink:=str_Link;將地址存入對象的屬性Flink中 end; FGroupKey_Link.Add(FKey_Link);//將對象存入對象數組 end; str_html:=copy(str_html,p2+1,length(str_html)-p2);//截取結束標識之后的文本,以便繼續搜索 p1:=pos('>',str_html); end; Result:=FGroupKey_Link; end; (3)利用計算機的多核優勢,在提取的文字內容中以并行方式搜索關鍵字,提取所需數據。 獲得網頁文本后,根據定義的關鍵字,對網頁文本進行匹配搜索以提取所需數據。 定義FKeyName為字符串數組,存放關鍵字,如FKeyName[0]:='分子靶向'; FKeyName [1]:='兒童食道';……FKeyName [7]:=’結直腸腫瘤' 。" 將FkeyName數組的元素分別帶入到isExist函數中,用isExist函數在存放網頁文字內容的對象數組FGroup中遍歷查詢關鍵字,若找到,返回真,將含有關鍵字的語句和鏈接地址存入數據庫中[16]。 本系統在isExist函數中采用了先進的并行編程技術。現在計算機都有多個 CPU單元,在開發中利用多核優勢進行并行編程[17-18],可以節約系統的運行時間,提高工作效率[19-20]。在Delphi xe7中,有一個簡化并行運行任務的庫,叫做并行編程庫。并行編程庫在System.Threading單元中,其中提供了很多有用的特性。使用并行庫,應把for循環用類函數TParallel.For替代,并傳遞一個匿名方法[21]。 關鍵代碼如下:function TForm1.isExist(str:string;webBrowser:TMozillaBrowser;isAll:Boolean=true):Boolean; var i,j:integer; FGroup:TObjectList; isExist:Boolean; begin isExist:=false; FGroup:=GetKey_Link(webBrowser);//從網頁中獲取文本內容,存入對象數組中 TParallel.For(1,FGroup.Count-1,procedure(I: Integer)//在數組中做關鍵字的遍歷查詢,找到返回真 begin if (isAll=true) then begin if (str=TKey_Link(FGroup[i]).Fkey) then//完全匹配 begin isExist:=true; break; end; end else begin if (pos(str,TKey_Link(FGroup[i]).Fkey)>0) then//部分匹配 begin isExist:=true; break; end; end; end); FreeAndNil(FGroup); Result:=isExist; end; 醫藥科學研究的一個關鍵環節是數據獲取。互聯網蘊含的海量數據具有免費、實時等特點,是重要的數據來源渠道。本文介紹的數據抓取技術,可有效從互聯網大量的信息中找到所需信息收集起來以供研究。所提供的Delhpi xe7示例代碼簡單、實用,可使人們依據需要,便捷準確地定制抓取方案,成為數據獲取的得力助手。 [1]Marty Butler,Andrew J Leone,Michael Willenborg.An empirical analysis of auditor reporting and its association with abnormal accruals[J].Journal of Accounting and Economics,2004. [2]Werner Antweiler,Murray Z Frank.Is all that talk just noise?The information content of Internet stock message boards[J].Journal of Finance,2004. [3]楊鎧懋.搜索引擎的研究與設計[D].電子科技大學,2010 [4]周立柱,林玲.聚焦爬蟲技術研究綜述[J].計算機應用,2005. [5]劉金紅,陸余良.主題網絡爬蟲研究綜述[J].計算機應用研究,2007. [6]李浩.網絡蜘蛛的研究與實現[J].科技信息,2012. [7]萬瑪寧,關永,韓相軍.嵌入式數據庫典型技術SQLite與BerKeley DB的研究[J].微計算機信息,2006. [8]宋麗娜.嵌入式數據庫典型技術-SQLite和BerKeley DB的研究[J].科技信息(學術研究),2008. [9]虞珊,周彩蘭,郭鳳玲.BerKeley DB在網絡信息挖掘中的應用[J].計算機與現代代,2008. [10]劉巍巍,徐成,李仁發.嵌入式數據庫Berkeley DB的原理與應用[J].科學技術與工程,2005. [11]徐娜,劉四維,汪翔,倪衛明.基于Bloom Filter的網頁去重算法[J].微型電腦應用,2011. [12]于振國.基于Bloom Filter的大規模網頁去重策略研究[J].現代圖書情報技術,2008. [13]李建宏,何玉珠.多線程技術在復雜數據采集系統中的應用.電子測量技術,2008. [14]眭俊華,劉慧娜,王建鑫等.多核多線程技術綜述[J].計算機應用,2013. [15]李鵬.多線程技術在數據通信中的應用[J].信息產業,2013. [16]盧超,梅衛峰,陳俊良等.基于感興趣度的WWW個性化信息發現[J].計算機科學,2002. [17]吳繼燕.多核技術及發展趨勢[J].哈爾濱軸承,2007. [18]李曉明,王韜,劉東,杜江凌.走進多核時代[J].計算機科學與探索,2008. [19]周偉明.多核計算與程序設計[M].武漢:華中科技大學出版社,2008. [20]Akhter S.多核程序設計技術[M].李寶峰,譯.北京:電子工業出版社,2008. [21]多核系列教材編寫組.多核程序設計[M].北京:清華大學出版社,2007.2.2 數據結構
2.3 使用布隆過濾器構建Visited表
2.4 使用多線程技術提高爬蟲的抓取速度
3 醫藥科研信息采集過程

3.1 網頁源文件內容獲取
3.2 下載網頁內容并解析
3.3 判斷網頁中是否含有所需的關鍵字



4 結束語