本發(fā)明涉及網(wǎng)絡(luò)信息處理技術(shù)領(lǐng)域,尤其涉及一種通用論壇正文提取方法。
背景技術(shù):
隨著互聯(lián)網(wǎng)的快速發(fā)展,論壇網(wǎng)頁數(shù)據(jù)量越來越龐大,匯聚著人類的知識(shí),反映了社會(huì)熱點(diǎn)。有效挖掘出論壇網(wǎng)頁的有價(jià)值信息,能使網(wǎng)頁信息得到更充分的利用,提升網(wǎng)頁數(shù)據(jù)的有用性。論壇包含大量有價(jià)值信息的同時(shí)也包含大量噪聲,而且由于不同論壇網(wǎng)頁的數(shù)據(jù)結(jié)構(gòu)各不相同,尋找一種通用的方法從網(wǎng)頁中提取有用信息變得更加困難。
若針對(duì)某一類型的網(wǎng)站根據(jù)其特定的標(biāo)簽和屬性來設(shè)計(jì)爬取算法,則無法滿足高效性和普遍性地提取。目前的通用新聞網(wǎng)站爬取算法主要利用新聞網(wǎng)頁的字符分布情況、正文字符量大以及內(nèi)容與主題的相關(guān)度等特性來提取信息,但不同論壇網(wǎng)頁的正文字符數(shù)變化幅度大,且發(fā)表和回貼的信息相對(duì)比較分散,故新聞網(wǎng)站的通用爬取算法對(duì)于論壇網(wǎng)頁這些算法難以取得理想的效果。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明提供一種通用論壇正文提取方法,以解決現(xiàn)有技術(shù)無法高效性、普遍性地從不同類型的論壇網(wǎng)頁中提取其有用信息的問題。
本發(fā)明提供一種通用論壇正文提取方法,包括以下步驟:
a、提取出網(wǎng)站完整的html代碼,探測該網(wǎng)頁編碼格式,并統(tǒng)一編碼為utf8格式;
b、解析html標(biāo)簽類型,獲得網(wǎng)頁的dom樹,提取標(biāo)題信息和包含發(fā)表時(shí)間信息的div標(biāo)簽內(nèi)容,過濾無用信息后對(duì)已提取信息進(jìn)行分類并生成列表;
c、計(jì)算列表數(shù)據(jù)長度,以時(shí)間為標(biāo)記分類列表信息并格式化輸出。
在本發(fā)明的通用論壇正文提取方法中,在步驟a之前還包括以下步驟:
向網(wǎng)站發(fā)送請(qǐng)求信息,在請(qǐng)求時(shí)添加headers,模仿瀏覽器請(qǐng)求;
通過瀏覽器返回的response,讀取cookie保存到本地,第二次訪問網(wǎng)站時(shí),在請(qǐng)求信息中添加保存在本地的cookie。
在本發(fā)明的通用論壇正文提取方法中,所述步驟a具體包括:
使用探測法對(duì)html代碼進(jìn)行解碼,首先采用utf8進(jìn)行解碼操作,如果成功,就返回解碼后的網(wǎng)頁內(nèi)容;否則再分別采用gb2312、gbk解碼,并統(tǒng)一編碼為utf8格式。
在本發(fā)明的通用論壇正文提取方法中,所述步驟b具體包括:
b1、基于已編碼為uft8格式的數(shù)據(jù),解析獲取網(wǎng)頁dom樹,提取<title>標(biāo)簽內(nèi)容即為論壇標(biāo)題;
b2、去掉網(wǎng)頁頭部和尾部的內(nèi)容,提取中間部分包含時(shí)間的div標(biāo)簽內(nèi)容;
b3、去除javascript、css代碼部分以及a標(biāo)簽內(nèi)容;
b4、應(yīng)用正則表達(dá)式匹配可能出現(xiàn)的時(shí)間格式,從上述步驟處理過的div標(biāo)簽中進(jìn)一步篩選出包含時(shí)間的孩子節(jié)點(diǎn),并提取出所述包含時(shí)間的孩子節(jié)點(diǎn)中的文本內(nèi)容,并過濾掉該孩子節(jié)點(diǎn)中其余的無用內(nèi)容和垃圾信息;
b5、以時(shí)間標(biāo)記分割字符串,對(duì)已提取的信息粗略分類,并生成列表。
在本發(fā)明的通用論壇正文提取方法中,所述步驟b2具體包括:
遍歷<body>的孩子節(jié)點(diǎn),去掉頭部和尾部的非div標(biāo)簽內(nèi)容,獲取中間部div標(biāo)簽;
應(yīng)用正則表達(dá)式逐個(gè)匹配所有可能出現(xiàn)的時(shí)間格式,搜索上述獲取的中間部分div的標(biāo)簽,提取包含時(shí)間的div標(biāo)簽內(nèi)容。
在本發(fā)明的通用論壇正文提取方法中,所述步驟c具體包括:
c1、計(jì)算所述列表的數(shù)據(jù)長度,如果數(shù)據(jù)長度等于3且只有一條時(shí)間信息則轉(zhuǎn)到步驟c2,如果數(shù)據(jù)長度大于3時(shí)則轉(zhuǎn)到步驟c3,如果數(shù)據(jù)長度等于2則轉(zhuǎn)到步驟c4;
c2、以時(shí)間為標(biāo)記將列表數(shù)據(jù)分割成三部分,根據(jù)字符比重去噪后轉(zhuǎn)到步驟c4;
c3、如果列表數(shù)據(jù)長度為2的倍數(shù),則轉(zhuǎn)到c4;否則判斷列表第一位數(shù)據(jù)和最后一位數(shù)據(jù)包含字符所占比重,去除字符所占比重少的一位數(shù)據(jù)后轉(zhuǎn)到步驟c4;
c4、列表中的數(shù)據(jù)去除噪聲后,根據(jù)列表第一位數(shù)據(jù)是否包含時(shí)間內(nèi)容確定列表格式;
c5、將列表數(shù)據(jù)轉(zhuǎn)換成字符串并寫入文件中,并將已提取的標(biāo)題和發(fā)表時(shí)間寫入文件。
在本發(fā)明的通用論壇正文提取方法中,所述步驟c2具體包括:
以時(shí)間為標(biāo)記將列表數(shù)據(jù)分割成第一位、第二位以及第三位;
判斷第一位數(shù)據(jù)和第三位數(shù)據(jù)的字符所占的比重,字符少的則認(rèn)為是噪聲,將它去掉。
在本發(fā)明的通用論壇正文提取方法中,所述步驟c4具體包括:
如果第一位數(shù)據(jù)包含時(shí)間內(nèi)容則列表的格式為時(shí)間在前、內(nèi)容在后;如果第一位數(shù)據(jù)不包含時(shí)間內(nèi)容則列表的格式為內(nèi)容在前、時(shí)間在后。
本發(fā)明的通用論壇正文提取方法至少包括以下有益效果:為有效挖掘出不同論壇網(wǎng)頁有用信息,本發(fā)明基于論壇網(wǎng)頁html文本的結(jié)構(gòu)特點(diǎn)以及網(wǎng)頁內(nèi)容的文字特點(diǎn),結(jié)合網(wǎng)頁的dom樹,采用解析標(biāo)簽方法對(duì)論壇網(wǎng)頁進(jìn)行信息提取和信息去噪,能夠準(zhǔn)確提取其主貼、回帖、標(biāo)題和發(fā)帖時(shí)間的相應(yīng)數(shù)據(jù)字段并格式化輸出,使論壇信息得到更好的利用。
附圖說明
圖1是本發(fā)明的通用論壇正文提取方法流程圖;
圖2為本發(fā)明實(shí)施例論壇網(wǎng)頁的dom樹簡圖。
具體實(shí)施方式
為使本發(fā)明的技術(shù)方案更加清晰,下面結(jié)合圖1所示的通用論壇正文提取方法流程圖詳細(xì)說明本發(fā)明的具體實(shí)施方式。
本發(fā)明的通用論壇正文提取方法包括如下步驟:
a、爬取數(shù)據(jù):抓取網(wǎng)站所有信息,即提取出網(wǎng)站完整的html代碼,探測該網(wǎng)頁編碼格式,并統(tǒng)一編碼為utf8格式以便于后續(xù)處理;
b、清洗數(shù)據(jù):基于已編碼為uft8格式的數(shù)據(jù),應(yīng)用beautifulsoup解析html標(biāo)簽類型,獲得網(wǎng)頁的dom樹,如圖2所示,提取標(biāo)題信息和包含發(fā)表時(shí)間信息的div標(biāo)簽內(nèi)容,過濾無用信息后對(duì)已提取信息進(jìn)行分類并生成列表;
c、格式化信息:計(jì)算列表數(shù)據(jù)長度,以時(shí)間為標(biāo)記分類信息并格式化輸出。
由于有些網(wǎng)站設(shè)置了反爬蟲機(jī)制,故在步驟a之前還包括反爬蟲處理步驟,針對(duì)反爬蟲的幾種常見情況進(jìn)行處理,具體包括:
(1)模擬瀏覽器請(qǐng)求:向網(wǎng)站發(fā)送請(qǐng)求信息,在請(qǐng)求時(shí)添加headers,headers里面包含user-agent,模仿瀏覽器請(qǐng)求;
(2)添加cookie:第一次訪問時(shí)由于沒有cookie,瀏覽器將拒絕訪問請(qǐng)求。通過瀏覽器返回的response,讀取cookie保存到本地,第二次訪問網(wǎng)站時(shí),在請(qǐng)求信息中添加保存在本地的cookie。
反爬蟲處理步驟后開始抓取網(wǎng)站所有信息,具體實(shí)施時(shí),步驟a包括數(shù)據(jù)解碼和編碼操作:
使用探測法對(duì)html代碼進(jìn)行解碼,首先嘗試使用utf8進(jìn)行解碼操作,如果成功,就返回解碼后的網(wǎng)頁內(nèi)容;否則再分別嘗試gb2312、gbk解碼,并統(tǒng)一編碼為utf8格式。已知國內(nèi)網(wǎng)站大部分編碼有utf8、gb2312、gbk三種,故針對(duì)這三種編碼,對(duì)爬取的內(nèi)容進(jìn)行解碼。
通過以上處理,成功爬取該網(wǎng)頁所有html數(shù)據(jù),下面進(jìn)入數(shù)據(jù)清洗步驟。
具體實(shí)施時(shí),步驟b具體包括如下步驟:
b1、提取標(biāo)題:基于已編碼為uft8格式的數(shù)據(jù),解析獲取網(wǎng)頁dom樹,提取<title>標(biāo)簽內(nèi)容即為論壇標(biāo)題,如圖2所示。
根據(jù)論壇網(wǎng)頁標(biāo)題與論壇的標(biāo)題一致的特點(diǎn),只需提取網(wǎng)頁的標(biāo)題作為論壇內(nèi)容的標(biāo)題,且網(wǎng)頁主要用<title>標(biāo)簽來顯示網(wǎng)站的標(biāo)題,故用beautifulsoup解析網(wǎng)頁dom樹,提取<title>標(biāo)簽內(nèi)容即為論壇標(biāo)題。經(jīng)過大量的測試表明,該方法有效可行,噪聲小。
b2、初步清洗:去掉網(wǎng)頁頭部和尾部的內(nèi)容,提取中間部分包含時(shí)間的div標(biāo)簽內(nèi)容。
通過訪問樣例網(wǎng)站發(fā)現(xiàn),論壇網(wǎng)站的構(gòu)成包括頭部、中間部和尾部。頭部主要是登錄、注冊(cè)和網(wǎng)站模塊等信息,尾部為發(fā)表回復(fù)、相關(guān)鏈接以及法律聲明,中間部里面的內(nèi)容包含了有用信息。通過查看網(wǎng)頁代碼發(fā)現(xiàn),中間部分都是用div標(biāo)簽分塊,論壇網(wǎng)頁中需要提取的內(nèi)容都包含在div標(biāo)簽中,故通過遍歷<body>的孩子節(jié)點(diǎn),判斷是否為div標(biāo)簽,去掉頭部和尾部等非div標(biāo)簽內(nèi)容,獲取中間部div標(biāo)簽的代碼,如圖2所示。
進(jìn)一步的,論壇類型網(wǎng)站中每層樓的發(fā)表信息都包含發(fā)表時(shí)間信息,故推斷所需內(nèi)容的div標(biāo)簽中一定包含時(shí)間信息。應(yīng)用正則表達(dá)式,逐個(gè)匹配所有可能出現(xiàn)的時(shí)間格式(如2017/4/24或2017年4月24日等格式),搜索已經(jīng)獲取的中間部div標(biāo)簽,通過判斷該div標(biāo)簽是否包含發(fā)表時(shí)間,提取包含時(shí)間的div標(biāo)簽內(nèi)容。
b3、去除噪聲:去除javascript、css代碼部分以及a標(biāo)簽內(nèi)容。
應(yīng)用正則表達(dá)式及beautifulsoup的extract函數(shù),去除javascript、css代碼部分以及a標(biāo)簽內(nèi)容。進(jìn)一步去除了該網(wǎng)頁的在b2步驟中已提取的div標(biāo)簽中的網(wǎng)頁設(shè)置代碼及廣告鏈接部分、相關(guān)內(nèi)容推薦鏈接等。
b4、提取正文和發(fā)表時(shí)間:應(yīng)用正則表達(dá)式匹配可能出現(xiàn)的時(shí)間格式,從上述步驟處理過的div標(biāo)簽中進(jìn)一步篩選出包含時(shí)間的孩子節(jié)點(diǎn),并提取出所述包含時(shí)間的孩子節(jié)點(diǎn)中的文本內(nèi)容,并過濾掉孩子節(jié)點(diǎn)中其余的無用內(nèi)容和垃圾信息;
通過beautifulsoup遍歷經(jīng)b1、b2、b3步驟處理后的div標(biāo)簽。雖然獲取的div標(biāo)簽包含了所需信息,但是也包含大量無用信息。為精確篩選出該網(wǎng)頁的有效信息,進(jìn)一步對(duì)已提取的div中包含發(fā)表時(shí)間的孩子節(jié)點(diǎn)進(jìn)行過濾,在上述處理過的div標(biāo)簽中,提取包含時(shí)間的文本內(nèi)容并過濾掉div標(biāo)簽中其余的無用內(nèi)容和垃圾信息。具體清洗工作如下:
b5、初步分類:以時(shí)間標(biāo)記分割字符串,對(duì)已提取的信息粗略分類,并生成列表。
由于主貼、每條回帖的div都包含時(shí)間信息且主帖在前、回帖在后,以時(shí)間標(biāo)記分割字符串,則可分出各樓層的信息,對(duì)已提取的信息進(jìn)行粗略分類,生成列表。
通過前面爬取、清洗、去噪、分類等操作,得到了包括時(shí)間和內(nèi)容的一串內(nèi)容數(shù)據(jù)列表,標(biāo)題內(nèi)容另外存儲(chǔ)。下面介紹將該內(nèi)容格式化存儲(chǔ)到硬盤。在已提取的信息中,標(biāo)題已提取完畢且無需進(jìn)一步去噪,但由于程序需要適應(yīng)所有的網(wǎng)站,在上面的操作中,并沒有對(duì)特定的網(wǎng)站格式進(jìn)行區(qū)分,即正文內(nèi)容與發(fā)表時(shí)間仍未區(qū)分,例如有些bbs網(wǎng)頁用戶發(fā)表內(nèi)容的結(jié)構(gòu)是發(fā)表時(shí)間在前,接著是發(fā)表的內(nèi)容;而有些網(wǎng)頁是發(fā)表內(nèi)容在前,發(fā)表時(shí)間在后。特別需要注意的是,在去噪過程中,對(duì)噪聲的處理并不是很完美,而這會(huì)給格式化成特定格式提高了難度。進(jìn)而進(jìn)一步提出了一種基于字符噪聲估計(jì)的算法將結(jié)果格式化成統(tǒng)一的格式。步驟c具體包括:
c1、計(jì)算所述列表的數(shù)據(jù)長度,如果數(shù)據(jù)長度等于3且只有一條時(shí)間信息,即只有主貼沒有回帖,此時(shí)轉(zhuǎn)到步驟c2;如果數(shù)據(jù)長度大于3時(shí),即同時(shí)含有主貼和回帖,此時(shí)轉(zhuǎn)到步驟c3;如果數(shù)據(jù)長度等于2,即只有主貼且沒有噪聲,此時(shí)轉(zhuǎn)到步驟c4。
c2、以時(shí)間為標(biāo)記將列表數(shù)據(jù)分割成三部分,根據(jù)字符比重去噪后轉(zhuǎn)到步驟c4;
具體實(shí)施時(shí),以時(shí)間標(biāo)記分割列表數(shù)據(jù),分割成第一位、第二位以及第三位,如:時(shí)間前的內(nèi)容、時(shí)間、時(shí)間后的內(nèi)容。根據(jù)字符比重去噪過程如下:
此時(shí)時(shí)間內(nèi)容在第二位,則判斷第一位數(shù)據(jù)和第三位數(shù)據(jù)的字符所占的比重,字符少的則認(rèn)為是噪聲,將它去掉。
c3、如果列表數(shù)據(jù)長度為2的倍數(shù),則轉(zhuǎn)到c4;否則判斷列表第一位數(shù)據(jù)和最后一位數(shù)據(jù)包含字符所占比重,去除字符所占比重少的一位數(shù)據(jù)后轉(zhuǎn)到步驟c4;
前面在形成列表的時(shí)候,每層樓的時(shí)間、正文依次間隔存儲(chǔ)。如果沒別的噪聲,則恰好是2的倍數(shù)。若不是2的倍數(shù),則需清除噪聲干擾。判斷列表數(shù)據(jù)長度能否被2整除,如果能則轉(zhuǎn)到c4。否則根據(jù)字符比重去噪:判斷列表第一位和最后一位數(shù)據(jù)的字符所占比重,如果第一位字符比較少,我們保留第二位到最后一位數(shù)據(jù),去除第一位;否則保留第一位到倒數(shù)第二位的數(shù)據(jù),去除最后一位數(shù)據(jù)。
c4、列表中的數(shù)據(jù)去除噪聲后,根據(jù)列表第一位數(shù)據(jù)是否包含時(shí)間內(nèi)容確定列表格式;
有些網(wǎng)站html里面提取出來的正文和時(shí)間信息前后順序不一樣,要區(qū)分出哪個(gè)是時(shí)間,哪個(gè)是正文,后面才能分類存儲(chǔ)。在前面的列表還沒有詳細(xì)判斷,故在這一步驟進(jìn)行判斷。去除了頭尾不需要的部分,如果列表第一位數(shù)據(jù)包含時(shí)間,則列表格式為時(shí)間在前,內(nèi)容在后;否則列表格式為內(nèi)容在前,時(shí)間在后。
c5、將列表數(shù)據(jù)轉(zhuǎn)換成字符串并寫入文件中,并將已提取的標(biāo)題和發(fā)表時(shí)間寫入文件。
遍歷列表,將列表數(shù)據(jù)轉(zhuǎn)換成字符串并寫入文件中,并將已提取的標(biāo)題和發(fā)表時(shí)間寫入文件;根據(jù)主貼在前回帖在后的原則,前面兩個(gè)元素內(nèi)容屬于主貼,后面的都分別屬于各層樓的回帖。
本發(fā)明的提取方法通用性強(qiáng),能夠適用于大多數(shù)論壇,能夠準(zhǔn)確提取其主貼、回帖、標(biāo)題和發(fā)帖時(shí)間的相應(yīng)數(shù)據(jù)字段并格式化輸出,使論壇信息得到更好的利用。
以上所述僅為本發(fā)明的較佳實(shí)施例,并不用以限制本發(fā)明的思想,凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。