深度剖析使用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 socket 超时设置 errno 10054
Jul 01 Python
详解JavaScript编程中的window与window.screen对象
Oct 26 Python
Python实现包含min函数的栈
Apr 29 Python
如何优雅地处理Django中的favicon.ico图标详解
Jul 05 Python
Python 进程之间共享数据(全局变量)的方法
Jul 16 Python
PyQtGraph在pyqt中的应用及安装过程
Aug 04 Python
python mysql 字段与关键字冲突的解决方式
Mar 02 Python
python查看矩阵的行列号以及维数方式
May 22 Python
Python常用数字处理基本操作汇总
Sep 10 Python
Pandas加速代码之避免使用for循环
May 30 Python
Python制作表白爱心合集
Jan 22 Python
Python 第三方库 openpyxl 的安装过程
Dec 24 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
利用Memcached在php下实现session机制 替换PHP的原生session支持
2010/08/21 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
2个比较经典的PHP加密解密函数分享
2014/07/01 PHP
PHP GD库生成图像的几个函数总结
2014/11/19 PHP
四个PHP非常实用的功能
2015/09/29 PHP
PHP框架Laravel学习心得体会
2015/10/28 PHP
PHP入门教程之数组用法汇总(创建,删除,遍历,排序等)
2016/09/11 PHP
laravel 5异常错误:FatalErrorException in Handler.php line 38的解决
2017/10/12 PHP
jQuery 使用手册(二)
2009/09/23 Javascript
javascript级联下拉列表实例代码(自写)
2013/05/10 Javascript
js 编码转换 gb2312 和 utf8 互转的2种方法
2013/08/07 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
2013/12/04 Javascript
JavaScript保留两位小数的2个自定义函数
2014/05/05 Javascript
深入对Vue.js $watch方法的理解
2017/03/20 Javascript
JavaScript原型对象、构造函数和实例对象功能与用法详解
2018/08/04 Javascript
微信小程序使用字体图标的方法
2019/05/23 Javascript
jQuery实现B2B网站后台管理系统侧导航
2020/07/08 jQuery
微信小游戏中three.js离屏画布的示例代码
2020/10/12 Javascript
如何使用JS console.log()技巧提高工作效率
2020/10/14 Javascript
[05:15]DOTA2英雄梦之声_第16期_灰烬之灵
2014/06/21 DOTA
Python使用jsonpath-rw模块处理Json对象操作示例
2018/07/31 Python
Python如何调用外部系统命令
2019/08/07 Python
Python 实现Image和Ndarray互相转换
2020/02/19 Python
什么是python的函数体
2020/06/19 Python
详解python tcp编程
2020/08/24 Python
HTML5使用ApplicationCache接口实现离线缓存技术解决离线难题
2012/12/13 HTML / CSS
大学四年职业生涯规划书范文
2014/01/02 职场文书
中秋节礼品促销方案
2014/02/02 职场文书
最新大学生创业计划书写作攻略
2014/04/02 职场文书
《黄山奇石》教学反思
2014/04/19 职场文书
十八大标语口号
2014/10/09 职场文书
2014年转正工作总结
2014/11/08 职场文书
离婚协议书范本(2016最新版)
2016/03/18 职场文书
vue2实现provide inject传递响应式
2021/05/21 Vue.js
详解Python描述符的工作原理
2021/06/11 Python
MySQL连表查询分组去重的实现示例
2021/07/01 MySQL