无关标签的一般长文本网页正文内容抽取
無關標簽的一般長文本網頁正文內容抽取
一般的網頁內容抽取需要針對特定的網站進行特定的檢查定位正文標簽,指定抽取規則。但是如果需要抽取100個不同內容結構的網站正文,需要的就是100個不同的規則。有沒有一種通用的內容抽取呢。可以只基于網頁正文內容的變化而變化的規則f(x).
本文實現的是針對于一般的長文本正文類網站(博客、新聞、小說類)實現的通用正文內容抽取。像那種需要抽取的正文內容C長度與網頁內容W長度比例C/W<0.5的可能會出現不適用的情況。(比如正文是一句話幾個字,整個頁面內容的文字長度超過了正文的2倍,那最好使用DOM標簽規則抽取)
以下的“網頁”均指長文本類型的網頁為什么抽取正文
一般的網頁正文都是屬于段落類型的文本,所屬標簽不一,其他的無用信息(如網頁版權、站點通知、導航內容等)也占據了一定的頁面內容,如果單純的把網頁內容文字全部抽取出來,
這很簡單,但是會夾雜很多的無用內容,干擾太大,所以針對正文抽取得到頁面的真正有用信息是主要目的。可以利用正文內容進行網頁相似度的計算。
怎么抽取正文
抽取正文要找到正文的分布特征,將爬取到的網頁去除所有標簽,得到每一行的內容后,可以根據(行號,字符數)制作圖表查看兩者的關聯:
下圖是騰訊新聞一則新聞頁面的行號-行字數關系圖表:
下圖是CSDN的兩則博文正文行號-行字數關系圖表:
《中文編碼相關,python處理gbk編碼的xml文件方法》:《python抓取gb2312gbk編碼網頁亂碼問題》:
下圖是segmentfault的一篇博文正文行號-行字數關系圖表:
《解決 ScriptError的另類思路》:可以看到,正文的內容一般是連續行的塊,因此我們可以設置閾值來過濾一些非正文的干擾行,但是針對某些連續行并不是有效正文的情況,就需要看這個連續行組成的塊的總字符數。
如果字數少于一個閾值,就不屬于正文,也就是正文的字符密度,由此可見,正文可以基于連續行字符密度來進行提取。
算法實現
假設我們已經爬取了網頁內容WebContent,并且將W的所有標簽去除得到了純文本保留行格式的文字內容LinesContent.接下來:
#三個可控變量,自由調整使抽取達到理想效果 #連續行閾值:連續多少行則認為是一個正文內容塊 threshold = 5 #正文內空行閾值:允許正文內容 段落或正文行 之間有多少空行 gap = 3 #正文字符密度閾值:每一行的字符數達到多少則認為屬于正文內容 density = 45#********初始化設置#******** #保留抽取結果字典,格式:{<連續塊字符總數>:<塊文字內容>,...} results={} #已經達到前后連續的次數 comobo_num =0 #當前連續塊的總字符數 combo_len = 0 #當前連續空行數 combo_null=0 #當前連續塊的文字內容 combo_text = '' #當前行/前一行的字符數 pre_len = 0for i in LinesContent:#當前行非空if i.strip():pre_len = len(i)comobo_num += 1 combo_null = 0combo_len += pre_len#疊加非空行內容到連續內容中combo_text = combo_text+i+ os.linesep#針對單行文本情況if len(a)==1 and pre_len >= density*threshold:results[pre_len]=combo_textelse:combo_null +=1#如果前一行非空if pre_len:#連續空行閾值判斷if combo_null > gap:#連續塊判斷if combo_len >= density*threshold \and comobo_num >= threshold:results[combo_len]=combo_textelse:continue#非正文連續塊則全部參數復位comobo_num = 0combo_len = 0 if combo_null > gap else combo_lenpre_len = 0combo_text = '' if combo_null > gap else combo_text經過對多個長文本類型網站的抓取抽取,正文抽取成功率達到了90%以上。
Todo
- 針對有圖片嵌入的正文抽取
- 連帶正文標簽的抽取
- 正文格式的保存
源碼地址:GitHub
總結
以上是生活随笔為你收集整理的无关标签的一般长文本网页正文内容抽取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 紧急通知!最新版CleanMyMac X
- 下一篇: 11-7笔记