一種基于期望列表的網頁內容抽取方法
【專利摘要】本發明公開了一種基于期望列表的網頁內容抽取方法,使用bison和flex庫將XPath表達式解析為鏈表結構;讀取XML文件文本;將XPath鏈表的頭節點加入到期望列表中;對于XML文本和XPath鏈表,根據狀態機的狀態,重復執行匹配行為。如果在期望列表中查詢到有名稱相同的項,則檢查該項對應的鏈表節點是否有下一個元素。如果有,將下一個元素加入期望列表中。如果沒有,表示XPath的匹配工作完成,將該節點作為結果返回。如果指針指向了標簽的末尾,則期望列表入棧,清理上下文。如果指針指向了閉合標簽的末尾,則期望列表出棧,還原上下文;當讀取指針指向XML文件的末尾時,則結束。本發明跳過不必要的分析。
【專利說明】一種基于期望列表的網頁內容抽取方法
【技術領域】
[0001]本發明屬于計算機【技術領域】,涉及一種基于期望列表的網頁內容抽取方法。
【背景技術】
[0002]Xpath是一種表達XML節點路徑的表達式,可以方便的定位到XML的一個節點。XPath的處理是網頁分析的一項常規工作,需要把一個網頁作為XML文件作為輸入流,給XPath引擎處理,最后輸出定位的文本。XPath的分析速度是整個網頁分析速度的關鍵之
O
[0003]處理XPath有多重方式。需要先用語法分析器將文本表達式轉換為內存結構,然后使用DOM樹模型的XML文檔表達并依此查詢。但是在網頁處理的環境中,這種做法因為內存和速度的關系,效果并不太好。所以之后有人提出了流式XPath的概念:它去除了原來XPath中定義的部分后退等元素,使得XPath的分析可以以一種一次掃描而不必來回移動的方式進行,所以速度得到了巨大的提高。流式XPath通常和SAX的XML模型結合工作,SAX模型不必建立內存節點,是一次遍歷的方式。速度更快,在這次遍歷工作中一邊分析XML元素,一邊處理XPath。這樣來實現流式XPath的規范要求。
[0004]嚴重依賴SAX分析因不同的SAX引擎而有不同的效果。但是在大部分情況下無法知道一個SAX引擎是否針對以下情況進行優化:1.同時分析多條XPath。2.錯誤檢測和錯誤恢復。3.跳過不必要的分析。其中第I點需要XPath分析器使用數據結構處理,第2點根據不同的SAX引擎有不同的效果。SAX通常的做法是對所有的節點都進行分析處理,然后使用回調函數通知上層。上層根據節點名稱選擇性的處理,不需要的節點就丟棄不處理。所以上面的第3點是無論如何也做不到的。
【發明內容】
[0005]為了克服現有技術中的缺陷,本發明提供一種基于期望列表的網頁內容抽取方法,提出期望列表的概念。該概念主要描述我們需要什么內容,就去查詢它,如果不需要這個內容,可以放心的忽略它。這實際上是受到人類自身處理XML的啟發,如果要我們自身拿著XPath結構去分析一個XML文件。那么我們自然也是一層一層的去查詢它,查到第一層才會去想查詢第二層。到此為止都和機器處理是一樣的,但是我們能夠跳過不需要的內容。例如我們查詢的XPath不包含任何屬性內容,那么我們自然不需要去注意XML節點的屬性。這樣的唯一好處就是能夠加速分析。
[0006]本發明期望列表的完整內容包含三方面的內容:
[0007]1.不使用結構化分析工具,僅僅使用字符串查找方式;
[0008]2.使用期望狀態機來指揮分析工作;
[0009]3.使用期望列表來表達查詢狀態。
[0010]具體技術方案為:
[0011]一種基于期望列表的網頁內容抽取方法,包括以下步驟:[0012]a.一開始,將狀態設置為 PARSE_BEGIN(b);
[0013]b.在PARSE_BEGIN中,清理所有列表的內容,準備進行新一輪的分析,并將所有XPath鏈表的第一個節點加入期望列表中,并將狀態設置為PARSE_TAG_BEG(c);
[0014]c.在PARSE_TAG_BEG中,查找第一個出現的'夕字符,并根據條件轉到相應的狀態:
[0015]如果開頭是〈!一,表明此節點是注釋節點,轉到PARSE_C0MMENT-BEG(1),
[0016]如果開頭是〈/,則出棧并轉入到PARSE_CHILD_TEXT(i)狀態.表明一個子節點的結束,
[0017]如果開頭是〈!**,表明此節點是動作節點,不必分析,則轉入PARSE_IGN0RE(j)狀態,
[0018]默認轉到PARSE_TAG 狀態(d);
[0019]d.在PARSE_TAG狀態中,掃描出一個不以空格'/'結束的字符串.并且查找期望列表中是否有匹配的項.如果有則看有沒有下一個XPath節點.沒有的話則表示查找完成.通知上層有結果.有的話則把下一個節點加入期望列表,
[0020]另外根據期望列表中是否要求處理屬性來決定轉移是到PARSE_ATTR_BEG(f)還是PARSE_TAG_END(e);
[0021]e.在PARSE_TAG_END中,掃描到'X字符.然后執行step_in操作.期望列表入棧,表明進入一個子節點.并轉移到PARSE_CHILD_TEXT(i)狀態;
.[0022]f.在 PARSE_ATTR_BEG 狀態直接轉移到 PARSE_ATTR (g)狀態;
[0023]g.在PARSE_ATTR狀態中如果出現,>'則轉為PARSE_ATTR_END (h).否則繼續掃描一個屬性,狀態不變;
[0024]h.在PARSE_ATTR_END狀態中,清理臨時變量,并轉為PARSE_TAG_END (e)狀態;
[0025]1.在PARSE_CHILD_TEXT狀態中,掃描到'〈'符號為止,中間的內容就是文本節點,查看是否有合適的文本搜集器,并轉為PARSE_TAG_BEG(c)狀態;
[0026]j.在PARSE_IGN0RE狀態中,掃描到'V符號為止,并直接轉為PARSE_TAG_BEG(c)狀態;
[0027]k.在PARSE_PASS狀態中,掃描到匹配的'〈[tag]'字符串,并轉為PARSE_TAG_BEG(c)狀態;
[0028]1.在 PARSE_COMMENT_BEG_PARSE_COMMENT PARSE_COMMENT_END 中掃描出一個<!——> 標簽,并轉為PARSE_TAG_BEG (c)狀態;
[0029]η.當掃描到文本的最后,停止掃描,分析完成。
[0030]本發明的有益效果:
[0031 ] 本發明在PARSE_TAG狀態根據期望列表的內容可以選擇性的處理屬性.目前只是配置了跳過屬性的分析,另外根據簡單的分析,屬性大約占了整個網頁的50%,所以通過這一步可以獲得近乎一倍的加速.[0032]狀態之間的轉移:例如進入PARSE_TAG_END狀態,則表示期望遇到一個’ >’標簽符號.所以通過字符串查找函數查找到’ >’符號.并繼續轉移狀態.如果從PARSE_TAG到PARSE_TAG_END,那么中間無論有沒有屬性,都直接跳過了.[0033]對于錯誤修正,把那些常見的不規范節點如meta, script等標簽放在專門的狀態中處理,無論它是不是有錯誤.都直接掠過.這樣就避免的錯誤檢查和錯誤恢復的相關步驟.【具體實施方式】
[0034]下面結合【具體實施方式】對本發明的技術方案作進一步詳細地說明。
[0035]一種基于期望列表的網頁內容抽取方法,包括以下步驟:
[0036]a.一開始,將狀態設置為 PARSE_BEGIN(b);
[0037]b.在PARSE_BEGIN中,目標是表明一次分析工作的開始,所以清理所有列表的內容,準備進行新一輪的分析,并將所有XPath鏈表的第一個節點加入期望列表中,并將狀態設置為 PARSE_TAG_BEG(c);
[0038]c.在PARSE_TAG_BEG中,目標是找到一個標簽的開始。需要查找第一個出現的' <'字符,并根據條件轉到相應的狀態:
[0039]如果開頭是〈!一,表明此節點是注釋節點。轉到PARSE_cOMMENT_BEG(I),
[0040]如果開頭是〈/,則出棧并轉到PARSE_CHILD_TEXT(i)狀態。表明一個子節點的結束,
[0041]如果開頭是〈!**,表明此節點是動作節點,不必分析。則轉入PARSE_IGN0RE(j)狀態,
[0042]默認轉到PARSE_TAG 狀態(C);
[0043]d.在PARSE_TAG狀態中,目標是識別一個標簽的名稱。掃描出一個不以‘空格’,
結束的字符串,即為標簽名稱。并且查找期望列表中是否有匹配的項。如果有則 看有沒有下一個XPath節點:沒有的話則表示查找完成,將結果返回給庫調用者。如果有的話則把下一個節點加入期望列表;
[0044]另外根據期望列表中是否要求處理屬性來決定轉移是到PARSE_ATTR_BEG(f)還是PARSE_TAG_END(d);
[0045]e.在PARSE_TAG_END中,需要將掃描頭指向標簽的結束位置,即掃描到'V字符,表示標簽的結束。然后執行step_in操作,將期望列表入棧,保存現場狀態。進入子節點,并轉移到PARSE_CHILD_TEXT(i)狀態;
[0046]f.在PARSE_ATTR_BEG狀態,執行attr_in過程。創建臨時儲存區,并直接轉移到PARSE_ATTR(g)狀態;
[0047]g.在PARSE_ATTR狀態的目標是識別一個屬性。一個屬性是類似key=value的結構,或者是只有key出現。所以需要掃描‘=’和‘空格’以及’>’,并且掃描出前后的key和value的值,并存入儲存區。將得到的key值和期望列表進行比對,如果發現有一樣的,表明搜索到了結果,同時查看是否有下一個XPath節點,如果沒有的話表明整條XPath查詢結束。將結果返回給調用者。如果有下一個節點,則將它加入到期望列表中。最后如果出現‘〉’則表明整個標簽都查詢完了,需要轉為PARSE_ATTR_END(h)。否則繼續回到PARSE_ATTR(g)狀態,掃描下一個屬性;
[0048]h.在PARSE_ATTR_END狀態中,需要執行attr_out過程,清理臨時儲存區,并轉為PARSE_TAG_END (d)狀態;
[0049]1.在PARSE_CHILD_TEXT狀態是為了掃描兩個節點之間的文本內容,該狀態是從PARSE_TAG_END狀態到達的,所以已經指向了一個標簽的結束了。因此掃描到' <'符號即下一個標簽的開始為止,中間的內容就是文本節點,查看是否有合適的文本搜集器\并轉為 PARSE_TAG_BEG (c)狀態;
[0050]j.在PARSE_IGN0RE狀態中,是為了處理一些二義性的標簽如<meta>,〈meta / > ;<br>, <br / >。這類不規范的情況本身會破壞XML的樹型結構造成錯誤,所以直接跳過標簽。掃描到' >'符號為止,并直接轉為PARSE_TAG_BEG(c)狀態;因為我們直接跳過了,也就不再需要額外的錯誤處理了;
[0051]k.在PARSE_PASS狀態中,同樣是為了跳過〈script〉和〈style〉這種內容格式復雜的標簽。和PARSE_IGN0RE不同的是其結束判定不一樣。后者之是以‘〉’字符結束,而前者需要掃描到'〈[tag]'標簽對應的閉合標簽〈/ [tag]〉,并轉為PARSE_TAG_BEG(c)狀態;
[0052]1.在 PARSE_COMMENT_BEG PARSE_C0MMENT PARSE_COMMENT_END 中掃描出了一個〈!——> 標簽,并轉為PARSE_TAG_BEG(c)狀態;分三個階段的意義是為了方便以后分析注釋用;
[0053]m.當掃描到文本的結束,即停止掃描,分析完成。
[0054]本發明用于快速抽取XML文檔的內容。并且可以用于和XML結構相似的HTML網頁。因此主要適用環境是網絡爬蟲,也就是網頁抽取功能。本發明可以提供快速的網頁處理速度,并且減少內存占用量。同時對網頁的一般錯誤也能夠很好的進行容錯處理,保證網絡爬蟲的可靠性。
[0055]同時還可以對配置文件的解析功能提供支持。大型程序的配置文件通常使用XML格式。本發明API簡潔,易于編程。能夠對項目快速編程提供有力的支持。
.[0056]以上所述,僅為本發明較佳的【具體實施方式】,本發明的保護范圍不限于此,任何熟悉本【技術領域】的技術人員在本發明披露的技術范圍內,可顯而易見地得到的技術方案的簡單變化或等效替換均落入本發明的保護范圍內。
【權利要求】
1.一種基于期望列表的網頁內容抽取方法,其特征在于,包括以下步驟: a.一開始,將狀態設置為PARSE_BEGIN(b); b.在PARSE_BEGIN中,清理所有列表的內容,準備進行新一輪的分析,并將所有XPath鏈表的第一個節點加入期望列表中,并將狀態設置為PARSE_TAG_BEG(c); c.在PARSE_TAG_BEG中,查找第一個出現的,夕字符,并根據條件轉到相應的狀態: 如果開頭是〈!一,表明此節點是注釋節點,轉到PARSE_C0MMENT_BEG(1), 如果開頭是〈/,則出棧并轉入到PARSE_CHILD_TEXT(i)狀態.表明一個子節點的結束, 如果開頭是〈!**,表明此節點是動作節點,不必分析,則轉入PARSE_IGNORE(j)狀態, 默認轉到PARSE_TAG狀態(d); d.在PARSE_TAG狀態中,掃描出一個不以空格'/'結束的字符串.并且查找期望列表中是否有匹配的項.如果有則看有沒有下一個XPath節點.沒有的話則表示查找完成.通知上層有結果.有的話則把下一個節點加入期望列表, 另外根據期望列表中是否要求處理屬性來決定轉移是到PARSE_ATTR_BEG(f)還是PARSE_TAG_END(e); e.在PARSE_TAG_END·中,掃描到'V字符.然后執行skp_in操作.期望列表入棧,表明進入一個子節點.并轉移到PARSE_CHILD_TEXT(i)狀態; f.在PARSE_ATTR_BEG狀態直接轉移到PARSE_ATTR(g)狀態; g.在PARSE_ATTR狀態中如果出現,>'則轉為PARSE_ATTR_END(h).否則繼續掃描一個屬性,狀態不變; h.在PARSE_ATTR_END狀態中,清理臨時變量,并轉為PARSE_TAG_END(e)狀態; 1.在PARSE_CHILD_TEXT狀態中,掃描到'<'符號為止,中間的內容就是文本節點,查看是否有合適的文本搜集器,并轉為PARSE_TAG_BEG(c)狀態; j.在PARSE_IGNORE狀態中,掃描到 > 符號為止,并直接轉為PARSE_TAG_BEG (c)狀態;k.在PARSE_PASS狀態中,掃描到匹配的'〈[tag]'字符串,并轉為PARSE_TAG_BEG(c)狀態; 1.在 PARSE_COMMENT_BEG_PARSE_COMMENT PARSE_COMMENT_END 中掃描出一個〈!——>標簽,并轉為PARSE_TAG_BEG(c)狀態; m.當掃描到文本的最后,停止掃描,分析完成。
【文檔編號】G06F17/30GK103440294SQ201310362840
【公開日】2013年12月11日 申請日期:2013年8月16日 優先權日:2013年8月16日
【發明者】王佰玲, 謝虎成, 黃俊恒, 宮名, 劉揚, 詹春燕 申請人:哈爾濱工業大學(威海)