zl程序教程

您现在的位置是:首页 >  后端

当前栏目

深度剖析使用python抓取网页正文的源码

Python网页源码 使用 深度 剖析 抓取 正文
2023-06-13 09:15:28 时间

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

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

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

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

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

步骤:

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

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

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

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

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

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

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

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

             其他标签的文本长度x4

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

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

完整代码

复制代码代码如下:


#coding:utf-8
importre

defremove_js_css(content):
   """removethethejavascriptandthestylesheetandthecommentcontent(<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)
   returns

defremove_empty_line(content):
   """removemultispace"""
   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)
   returns

defremove_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)
   returns

defremove_video(s,n=1000):
   video="a"*n
   r=re.compile(r"""<embed.*?>""",re.I|re.M|re.S)
   s=r.sub(video,s)
   returns

defsum_max(values):
   cur_max=values[0]
   glo_max=-999999
   left,right=0,0
   forindex,valueinenumerate(values):
       cur_max+=value
       if(cur_max>glo_max):
           glo_max=cur_max
           right=index
       elif(cur_max<0):
           cur_max=0

   foriinrange(right,-1,-1):
       glo_max-=values[i]
       ifabs(glo_max<0.00001):
           left=i
           break
   returnleft,right+1

defmethod_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)-8
       group_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])

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