深度剖析使用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使用pylab库实现画线功能的方法详解
Jun 08 Python
Python中一行和多行import模块问题
Apr 01 Python
pygame游戏之旅 添加键盘按键的方法
Nov 20 Python
python判断一个数是否能被另一个整数整除的实例
Dec 12 Python
Python反爬虫技术之防止IP地址被封杀的讲解
Jan 09 Python
Python整数与Numpy数据溢出问题解决
Sep 11 Python
解决pycharm上的jupyter notebook端口被占用问题
Dec 17 Python
np.random.seed() 的使用详解
Jan 14 Python
git查看、创建、删除、本地、远程分支方法详解
Feb 18 Python
使用python库xlsxwriter库来输出各种xlsx文件的示例
Sep 01 Python
Python学习工具jupyter notebook安装及用法解析
Oct 23 Python
如何在Python中妥善使用进度条详解
Apr 05 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
php 动态执行带有参数的类方法
2009/04/10 PHP
PHP跨平台获取服务器IP地址自定义函数分享
2014/12/29 PHP
PHP使用phpunit进行单元测试示例
2019/09/23 PHP
YII2框架中使用RBAC对模块,控制器,方法的权限控制及规则的使用示例
2020/03/18 PHP
jQuery 性能优化指南(3)
2009/05/21 Javascript
js 页面刷新location.reload和location.replace的区别小结
2009/12/24 Javascript
基于jquery的textarea发布框限制文字字数输入(添加中文识别)
2012/02/16 Javascript
比较不错的JS/JQuery显示或隐藏文本的方法
2014/02/13 Javascript
js和jquery中循环的退出和继续学习记录
2014/09/06 Javascript
javascript求日期差的方法
2016/03/02 Javascript
jQuery插件 Jqplot图表实例
2016/06/18 Javascript
node.js中的事件处理机制详解
2016/11/26 Javascript
jQuery DateTimePicker 日期和时间插件示例
2017/01/22 Javascript
Windows下Node.js安装及环境配置方法
2017/09/18 Javascript
原生JS实现ajax与ajax的跨域请求实例
2017/12/01 Javascript
elementui的默认样式修改方法
2018/02/23 Javascript
详解Js里的for…in和for…of的用法
2019/03/28 Javascript
在Python中使用Neo4j数据库的教程
2015/04/16 Python
机器学习python实战之决策树
2017/11/01 Python
Linux CentOS Python开发环境搭建教程
2018/11/28 Python
PIL图像处理模块paste方法简单使用详解
2019/07/17 Python
python 模拟银行转账功能过程详解
2019/08/06 Python
百思买加拿大:Best Buy Canada
2018/03/20 全球购物
施华洛世奇波兰官网:SWAROVSKI波兰
2019/06/18 全球购物
苏格兰领先的多渠道鞋店:Begg Shoes
2019/10/22 全球购物
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
高级Java程序员面试题
2016/06/23 面试题
物流专业大学应届生求职信
2013/11/03 职场文书
父亲生日宴会答谢词
2014/01/10 职场文书
领导干部培训感言
2014/01/23 职场文书
教师工作失职检讨书
2014/09/18 职场文书
2014年政风行风自查自纠报告
2014/10/21 职场文书
精神文明建设汇报材料
2014/12/24 职场文书
出国留学导师推荐信
2015/03/26 职场文书
2015年度酒店客房部工作总结
2015/05/25 职场文书
几款流行的HTML5 UI框架比较(小结)
2021/04/08 HTML / CSS