微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

网页正文及内容图片提取算法

2015-10-03 20:33 前端大全

(点击上方,可快速关注)


作者:rainy

网址:http://blog.rainy.im/2015/09/02/web-content-and-main-image-extractor/


问题:如何提取任意(尤其是新闻、资讯类)网页的正文内容,提取与文章内容相关的图片,源码可见:extractor.py。


抓取单个网站网页内容时通常采用正则匹配的方式,但不同网站之间结构千奇百怪,很难用统一的正则表达式进行匹配。《基于行块分布函数的通用网页正文抽取算法》的作者总结了一般从网页中提取文章正文的方法,提出基于行块分布的正文抽取算法,并给出了 PHP 、Java 等实现。这一算法的主要原理基于两点:


  1. 正文区密度:在去除HTML中所有tag之后,正文区字符密度更高,较少出现多行空白;

  2. 行块长度:非正文区域的内容一般单独标签(行块)中较短。


算法步骤如下:


  • 去除所有tag,包括样式、Js脚本内容等,但保留原有的换行符 \n:


reCOMM = r'<!--.*?-->'

reTRIM = r'<{0}.*?>([\s\S]*?)<\/{0}>'

reTAG = r'<[\s\S]*?>|[ \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


将网页内容按行分割,定义行块 block i 为第 [i,i+blockSize] 行文本之和并给出行块长度基于行号的分布函数:


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


正文出现在最长的行块,截取两边至行块长度为 0 的范围:


def getContext(ctexts, cblocks):

maxTextLen = max(cblocks)

start = end = cblocks.index(maxTextLen)

while start > 0 and cblocks[start] > min(textLens):

start -= 1

while end < lines - blockSize and cblocks[end] > min(textLens):

self.end += 1

return "".join(ctexts[start:end])


如果需要提取正文区域出现的图片,只需要在第一步去除tag时保留<img>标签的内容:


reIMG = re.compile(r'<img[\s\S]*?src=[\'|"]([\s\S]*?)[\'|"][\s\S]*?>')

def processImages(body):

return reIMG.sub(r'{{\1}}', body)


总结


以上算法基本可以应对大部分(中文)网页正文的提取,针对有些网站正文图片多于文字的情况,可以采用保留<img> 标签中图片链接的方法,增加正文密度。目前少量测试发现的问题有:1)文章分页或动态加载的网页;2)评论长度过长喧宾夺主的网页。


参考


  • cx-extractor

  • cix-extractor-py




前端大全

微信号:FrontDev

打造东半球最好的 前端技术 微信号

--------------------------------------

商务合作QQ:2302462408

投稿网址:top.jobbole.com

 
前端大全 更多文章 5个典型的JavaScript面试题(上) Limu:JavaScript的那些书 Web开发:我希望得到的编程学习路线图 JavaScript基础工具清单 常用排序算法之JavaScript实现
猜您喜欢 C#几个经常犯错误汇总 【长文章】张小龙内部讲座《通过微信谈产品》【上】 PHP老师没教过你的那些知识点 匿名Email:分享几个10分钟邮箱(即弃型电子邮箱)! 如何成为一名真正的数据分析师或者数据工程师