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


Posted in Python onJune 11, 2014

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

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

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

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

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

步骤:

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

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

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

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

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

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

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

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

              其他标签的文本长度 x4

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

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

完整代码

#coding:utf-8
import re
def remove_js_css (content):
    """ remove the the javascript and 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)
    return s
def remove_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)
    return s
def remove_any_tag (s):
    s = re.sub(r'''<[^>]+>''','',s)
    return s.strip()
def remove_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)
    return len(''.join(text)),len(text_b)
def remove_image (s,n=50):
    image = 'a' * n
    r = re.compile (r'''<img.*?>''',re.I|re.M|re.S)
    s = r.sub(image,s)
    return s
def remove_video (s,n=1000):
    video = 'a' * n
    r = re.compile (r'''<embed.*?>''',re.I|re.M|re.S)
    s = r.sub(video,s)
    return s
def sum_max (values):
    cur_max = values[0]
    glo_max = -999999
    left,right = 0,0
    for index,value in enumerate (values):
        cur_max += value
        if (cur_max > glo_max) :
            glo_max = cur_max
            right = index
        elif (cur_max < 0):
            cur_max = 0
    for i in range(right, -1, -1):
        glo_max -= values[i]
        if abs(glo_max < 0.00001):
            left = i
            break
    return left,right+1
def method_1 (content, k=1):
    if not content:
        return None,None,None,None
    tmp = content.split('\n')
    group_value = []
    for i in range(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)
    return left,right, len('\n'.join(tmp[:left])), len ('\n'.join(tmp[:right]))
def extract (content):
    content = remove_empty_line(remove_js_css(content))
    left,right,x,y = method_1 (content)
    return '\n'.join(content.split('\n')[left:right])

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

Python 相关文章推荐
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
Jul 30 Python
深入理解Django的自定义过滤器
Oct 17 Python
Python回文字符串及回文数字判定功能示例
Mar 20 Python
python 读入多行数据的实例
Apr 19 Python
在cmd命令行里进入和退出Python程序的方法
May 12 Python
使用python 3实现发送邮件功能
Jun 15 Python
Django migrations 默认目录修改的方法教程
Sep 28 Python
Python中extend和append的区别讲解
Jan 24 Python
Python3之手动创建迭代器的实例代码
May 22 Python
python实现手势识别的示例(入门)
Apr 15 Python
keras的load_model实现加载含有参数的自定义模型
Jun 22 Python
Android Q之气泡弹窗的实现示例
Jun 23 Python
python k-近邻算法实例分享
Jun 11 #Python
浅析python 内置字符串处理函数的使用方法
Jun 11 #Python
python使用正则表达式检测密码强度源码分享
Jun 11 #Python
Python查看多台服务器进程的脚本分享
Jun 11 #Python
Python SQLite3数据库操作类分享
Jun 10 #Python
Python不规范的日期字符串处理类
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之数据查询实例
Jun 10 #Python
You might like
Zend Studio 无法启动的问题解决方法
2008/12/04 PHP
在wamp集成环境下升级php版本(实现方法)
2013/07/01 PHP
php 字符串压缩方法比较示例
2014/01/23 PHP
PHP正则匹配反斜杠'\'和美元'$'的方法
2017/02/08 PHP
PHP echo()函数讲解
2019/02/15 PHP
php创建类并调用的实例方法
2019/09/25 PHP
Z-Blog中用到的js代码
2007/03/15 Javascript
HTML DOM的nodeType值介绍
2011/03/31 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
jQuery简易图片放大特效示例代码
2014/06/09 Javascript
js实现透明度渐变效果的方法
2015/04/10 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
详解JavaScript基本类型和引用类型
2015/12/09 Javascript
关于javascript的一些知识以及循环详解
2016/09/12 Javascript
JavaScript模仿Pinterest实现图片预加载功能
2016/10/25 Javascript
BootStrap+Mybatis框架下实现表单提交数据重复验证
2017/03/23 Javascript
JS变量及其作用域
2017/03/29 Javascript
Vue.js中数据绑定的语法教程
2017/06/02 Javascript
Vue中插入HTML代码的方法
2018/09/21 Javascript
JavaScript偏函数与柯里化实例详解
2019/03/27 Javascript
Javascript实现鼠标点击冒泡特效
2019/12/24 Javascript
Python中使用Inotify监控文件实例
2015/02/14 Python
浅析python实现scrapy定时执行爬虫
2018/03/04 Python
python3之模块psutil系统性能信息使用
2018/05/30 Python
python事件驱动event实现详解
2018/11/21 Python
基于Python模拟浏览器发送http请求
2020/11/06 Python
使用HTML和CSS3绘制基本卡通图案的示例分享
2015/11/06 HTML / CSS
建筑专业自荐信
2013/10/18 职场文书
校园广播稿500字
2014/02/04 职场文书
内刊编辑求职自荐书范文
2014/02/19 职场文书
意向协议书范本
2014/04/23 职场文书
行政文员实习自我鉴定范文
2014/09/14 职场文书
评先进个人材料
2014/12/29 职场文书
中秋节感想
2015/08/10 职场文书
股东协议书范本2016
2016/03/21 职场文书