按示例学python:使用python抓取网页正文

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

平时打开一个网页,除了文章的正文内容,通常会有一大堆的导航,广告和其他方面的信息。本博客的目的,在于说明如何从一个网页中提取出文章的正文内容,而过渡掉其他无关的的信息。

这里先看看 demo :http://2.tingxinwen.duapp.com/extract_context

本方法是基于文本密度的方法,最初的想法来源于哈工大的《基于行块分布函数的通用网页正文抽取算法》,本文基于此进行一些小修改。

约定:

本文基于网页的不同行来进行统计,因此,假设网页内容是没有经过压缩的,就是网页有正常的换行的。

有些新闻网页,可能新闻的文本内容比较短,但其中嵌入一个视频文件,因此,我会给予视频较高的权重;这同样适用于图片,这里有一个不足,应该是要根据图片显示的大小来决定权重的,但本文的方法未能实现这一点。

由于广告,导航这些非正文内容通常以超链接的方式出现,因此文本将给予超链接的文本权重为零。

这里假设正文的内容是连续的,中间不包含非正文的内容,因此实际上,提取正文内容,就是找出正文内容的开始和结束的位置。

步骤:

首先清除网页中CSS,javascript,注释,Meta,Ins这些标签里面的内容,清除空白行。

计算每一个行的经过处理的数值(1)

计算上面得出的每行文本数的最大正子串的开始结束位置

其中第二步需要说明一下:

对于每一行,我们需要计算一个数值,这个数值的计算如下:

一个图片标签img,相当于出现长度为50字符的文本 (给予的权重),x1,

一个视频标签embed,相当于出现长度为1000字符的文本, x2

一行内所有链接的标签 a 的文本长度 x3 ,

其他标签的文本长度 x4

每行的数值 = 50 * x1其出现次数 + 1000 * x2其出现次数 + x4 – 8

//说明, -8 因为我们要计算一个最大正子串,因此要减去一个正数,至于这个数应该多大,我想还是按经验来吧。

完整代码

#coding:utf-8importredefremove_js_css (content):"""remove the theJavascriptand the stylesheet and the comment content (<script>....</script> and <style>....</style> <!-- xxx -->)"""r= re.compile(r'''<script.*?</script>''',re.I|re.M|re.S)

s= r.sub ('',content)

r= re.compile(r'''<style.*?</style>''',re.I|re.M|re.S)

s= r.sub ('', s)

r= re.compile(r'''<!--.*?-->''', re.I|re.M|re.S)

s= r.sub('',s)

r= re.compile(r'''<meta.*?>''', re.I|re.M|re.S)

s= r.sub('',s)

r= re.compile(r'''<ins.*?</ins>''', re.I|re.M|re.S)

s= r.sub('',s)returnsdefremove_empty_line (content):"""remove multi space"""r= re.compile(r'''^\s+$''', re.M|re.S)

s= r.sub ('', content)

r= re.compile(r'''\n+''',re.M|re.S)

s= r.sub('\n',s)returnsdefremove_any_tag (s):

s= re.sub(r'''<[^>]+>''','',s)returns.strip()defremove_any_tag_but_a (s):

text= re.findall (r'''<a[^r][^>]*>(.*?)</a>''',s,re.I|re.S|re.S)

text_b=remove_any_tag (s)returnlen(''.join(text)),len(text_b)defremove_image (s,n=50):

image='a'*n

r= re.compile (r'''<img.*?>''',re.I|re.M|re.S)

s=r.sub(image,s)returnsdefremove_video (s,n=1000):

video='a'*n

r= re.compile (r'''<embed.*?>''',re.I|re.M|re.S)

s=r.sub(video,s)returnsdefsum_max (values):

cur_max=values[0]

glo_max= -999999left,right=0,0forindex,valueinenumerate (values):

cur_max+=valueif(cur_max >glo_max) :

glo_max=cur_max

right=indexelif(cur_max <0):

cur_max=0foriinrange(right, -1, -1):

glo_max-=values[i]ifabs(glo_max < 0.00001):

left=i

breakreturnleft,right+1defmethod_1 (content, k=1):ifnotcontent:returnNone,None,None,None

tmp= content.split('\n')

group_value=[]foriinrange(0,len(tmp),k):

group='\n'.join(tmp[i:i+k])

group=remove_image (group)

group=remove_video (group)

text_a,text_b=remove_any_tag_but_a (group)

temp= (text_b - text_a) - 8group_value.append (temp)

left,right=sum_max (group_value)returnleft,right, len('\n'.join(tmp[:left])), len ('\n'.join(tmp[:right]))defextract (content):

content=remove_empty_line(remove_js_css(content))

left,right,x,y=method_1 (content)return'\n'.join(content.split('\n')[left:right])

代码 从最后一个函数开始调用。

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航