→ Original post ←
问题:如何提取任意(尤其是新闻、资讯类)网页的正文内容,提取与文章内容相关的图片,源码可见:extractor.py。
抓取单个网站网页内容时通常采用正则匹配的方式,但不同网站之间结构千奇百怪,很难用统一的正则表达式进行匹配。《基于行块分布函数的通用网页正文抽取算法》的作者总结了一般从网页中提取文章正文的方法,提出基于行块分布的正文抽取算法,并给出了 PHP 、 Java 等实现。这一算法的主要原理基于两点:
算法步骤如下:
\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
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 < lines - blockSize and cblocks[end] > min (textLens ):
self.end += 1
return "".join (ctexts[start:end])
<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 )评论长度过长喧宾夺主的网页。
1
Tink 2015-09-03 04:48:52 +08:00 via iPhone
有想法
|
2
gamexg 2015-09-03 13:37:24 +08:00 via Android
感觉多网页对比更清楚吧?
同一个网站 url 类似的布局应该一致,比较不同的部分就可以找到标题内容广告等块。 |
3
jeremaihloo 2015-09-03 22:37:35 +08:00 via Android 1
|
4
irainy OP @jeremaihloo cool!
|
5
piapia 2015-12-20 00:31:12 +08:00
觉得印象笔记的 chrome 插件提取的很准确
|