深度剖析使用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实现系统状态监测和故障转移实例方法
Nov 18 Python
videocapture库制作python视频高速传输程序
Dec 23 Python
python中sys.argv参数用法实例分析
May 20 Python
利用Python爬虫给孩子起个好名字
Feb 14 Python
Python MySQL数据库连接池组件pymysqlpool详解
Jul 07 Python
pycharm下查看python的变量类型和变量内容的方法
Jun 26 Python
对python numpy.array插入一行或一列的方法详解
Jan 29 Python
python中用logging实现日志滚动和过期日志删除功能
Aug 20 Python
python opencv图像处理(素描、怀旧、光照、流年、滤镜 原理及实现)
Dec 10 Python
python excel和yaml文件的读取封装
Jan 12 Python
Python与C/C++的相互调用案例
Mar 04 Python
Python中json.dumps()函数的使用解析
May 17 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
Yii Framework框架获取分类下面的所有子类方法
2014/06/20 PHP
YII视图整合kindeditor扩展的方法
2016/07/13 PHP
Extjs学习笔记之五 一个小细节renderTo和applyTo的区别
2010/01/07 Javascript
jQuery EasyUI API 中文文档 搜索框
2011/09/29 Javascript
设置jsf的选择框h:selectOneMenu为不可编辑状态的方法
2014/01/07 Javascript
jQuery $命名冲突解决方案汇总
2014/11/13 Javascript
JS简单循环遍历json数组的方法
2016/04/22 Javascript
JavaScript 对象字面量讲解
2016/06/06 Javascript
Javascript动画效果(3)
2016/10/11 Javascript
AngularJS前端页面操作之用户修改密码功能示例
2017/03/27 Javascript
AngularJS实现进度条功能示例
2017/07/05 Javascript
微信小程序返回多级页面的实现方法
2017/10/27 Javascript
js时间戳与日期格式之间相互转换
2017/12/11 Javascript
基于axios封装fetch方法及调用实例
2018/02/05 Javascript
Vue中$refs的用法详解
2018/06/24 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
layui实现下拉复选功能的例子(包括数据的回显与上传)
2019/09/24 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
jQuery实现动态加载瀑布流
2020/09/01 jQuery
解决iView Table组件宽度只变大不变小的问题
2020/11/13 Javascript
vue 实现click同时传入事件对象和自定义参数
2021/01/29 Vue.js
python fabric实现远程部署
2017/01/05 Python
python多线程之事件Event的使用详解
2018/04/27 Python
python 2.7 检测一个网页是否能正常访问的方法
2018/12/26 Python
分享8个非常流行的 Python 可视化工具包
2019/06/05 Python
浅谈opencv自动光学检测、目标分割和检测(连通区域和findContours)
2020/06/04 Python
tensorflow 2.1.0 安装与实战教程(CASIA FACE v5)
2020/06/30 Python
俄罗斯宠物用品网上商店:ZooMag
2019/12/12 全球购物
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
什么是方法的重载
2013/06/24 面试题
大学生村官典型材料
2014/01/12 职场文书
学校党支部承诺书
2015/04/30 职场文书
老乡会致辞
2015/07/28 职场文书
班级班风口号大全
2015/12/25 职场文书
mybatis源码解读之executor包语句处理功能
2022/02/15 Java/Android
如何让你的Nginx支持分布式追踪详解
2022/07/07 Servers