抓取网页新闻(基于行块分布函数的通用网页正文抽取算法(图))
优采云 发布时间: 2021-10-24 07:00抓取网页新闻(基于行块分布函数的通用网页正文抽取算法(图))
问题:如何提取任意网页的正文内容(尤其是新闻和资讯),提取与文章内容相关的图片,源码见:extractor.py。
抓取单个网站网页内容时,通常使用正则匹配。但是不同的网站的结构实在是太奇怪了,很难用统一的正则表达式来匹配。《基于行块分布函数的通用网页文本提取算法》作者总结了从网页中提取文章文本的通用方法,提出了一种基于行块分布的文本提取算法,并给出了PHP等实现和爪哇。. 该算法的主要原理基于两点:
正文区域密度:去除HTML中所有标签后,正文区域字符密度更高,多行空白更少;行块长度:单个标签(行块)中非文本区域的内容一般较短。
算法步骤如下:
reCOMM = r''
reTRIM = r'([\s\S]*?)'
reTAG = r'|[ \t\r\f\v]'
def processTags(body=""):
body = re.sub(reCOMM, "", body)
body = re.sub(reTRIM.format("script"), "" ,re.sub(reTRIM.format("style"), "", body))
body = re.sub(reTAG, "", body)
return body
def processBlocks(body=""):
ctexts = body.split("\n")
textLens = [len(text) for text in ctexts]
cblocks = [0] * (len(ctexts) - blockSize)
lines = len(ctexts)
for i in range(blockSize):
cblocks = list(map(lambda x,y: x+y, textLens[i : lines-1-blockSize+i], cblocks))
return cblocks
def getContext(ctexts, cblocks):
maxTextLen = max(cblocks)
start = end = cblocks.index(maxTextLen)
while start > 0 and cblocks[start] > min(textLens):
start -= 1
while end min(textLens):
self.end += 1
return "".join(ctexts[start:end])
reIMG = re.compile(r'')
def processImages(body):
return reIMG.sub(r'{{\1}}', body)
总结
上述算法基本可以处理大部分(中文)网页文本的提取。对于某些网站文字图片多于文字的情况,可以使用retention
在标签中链接图像的方法增加了文本的密度。目前在少数测试中发现的问题包括:1)文章分页或动态加载网页;2) 网页评论太长。
参考
推特脸书谷歌+
Python算法