深度剖析使用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之wxPython应用实例
Sep 28 Python
在Django中同时使用多个配置文件的方法
Jul 22 Python
python中MethodType方法介绍与使用示例
Aug 03 Python
利用Python将时间或时间间隔转为ISO 8601格式方法示例
Sep 05 Python
pandas 对series和dataframe进行排序的实例
Jun 09 Python
Python数据分析matplotlib设置多个子图的间距方法
Aug 03 Python
Python3非对称加密算法RSA实例详解
Dec 06 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
Jul 03 Python
python设置表格边框的具体方法
Jul 17 Python
Python 代码调试技巧示例代码
Aug 11 Python
Python 实现定积分与二重定积分的操作
May 26 Python
聊聊基于pytorch实现Resnet对本地数据集的训练问题
Mar 25 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中根据某年第几天计算出日期年月日的代码
2011/02/24 PHP
php学习笔记之 函数声明
2011/06/09 PHP
php中的注释、变量、数组、常量、函数应用介绍
2012/11/16 PHP
保存到桌面、设为桌面且带图标的PHP代码
2013/11/19 PHP
php身份证号码检查类实例
2015/06/18 PHP
PHP实现留言板功能的详细代码
2017/03/25 PHP
js计算页面刷新的次数
2009/07/20 Javascript
JavaScript Event学习第八章 事件的顺序
2010/02/07 Javascript
JavaScript 内置对象属性及方法集合
2010/07/04 Javascript
基于jQuery实现简单的折叠菜单效果
2015/11/23 Javascript
最棒的Angular2表格控件
2016/08/10 Javascript
JS实现动态增加和删除li标签行的实例代码
2016/10/16 Javascript
JS判断是否手机或pad访问实现方法
2016/12/09 Javascript
Vue-Router模式和钩子的用法
2018/02/28 Javascript
微信小程序实现长按删除图片的示例
2018/05/18 Javascript
关于自定义Egg.js的请求级别日志详解
2018/12/12 Javascript
vuejs移动端实现div拖拽移动
2019/07/25 Javascript
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
es6数组之扩展运算符操作实例分析
2020/04/25 Javascript
[04:50]2019DOTA2高校联赛秋季赛四强集锦
2019/12/27 DOTA
Python之文字转图片方法
2018/05/10 Python
twilio python自动拨打电话,播放自定义mp3音频的方法
2019/08/08 Python
python模块和包的应用BASE_PATH使用解析
2019/12/14 Python
详解python常用命令行选项与环境变量
2020/02/20 Python
python GUI库图形界面开发之PyQt5打印控件QPrinter详细使用方法与实例
2020/02/28 Python
VSCode配合pipenv搞定虚拟环境的实现方法
2020/05/17 Python
台湾屈臣氏网路商店:Watsons台湾
2020/12/29 全球购物
企划专员岗位职责
2013/12/09 职场文书
物业工作计划书
2014/01/10 职场文书
村官工作鉴定评语
2014/01/27 职场文书
素质拓展感言
2014/01/29 职场文书
幼儿园庆六一游园活动方案
2014/01/29 职场文书
供用电专业求职信
2014/07/07 职场文书
驾驶员安全责任书
2014/07/22 职场文书
简历自我评价模板
2015/03/11 职场文书
MySQL中EXPLAIN语句及用法
2022/05/20 MySQL