深度剖析使用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类继承用法实例分析
Oct 10 Python
python 字典(dict)按键和值排序
Jun 28 Python
python实现字符串连接的三种方法及其效率、适用场景详解
Jan 13 Python
Python中支持向量机SVM的使用方法详解
Dec 26 Python
Python-OpenCV基本操作方法详解
Apr 02 Python
Django 过滤器汇总及自定义过滤器使用详解
Jul 19 Python
简单介绍python封装的基本知识
Aug 10 Python
pytorch 自定义卷积核进行卷积操作方式
Dec 30 Python
Pytorch to(device)用法
Jan 08 Python
Python 随机生成测试数据的模块:faker基本使用方法详解
Apr 09 Python
Python读取文件夹下的所有文件实例代码
Apr 02 Python
python如何获取网络数据
Apr 11 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
mac下使用brew配置环境的步骤分享
2011/05/23 PHP
php中mysql操作buffer用法详解
2015/03/19 PHP
PHP基于文件存储实现缓存的方法
2015/07/20 PHP
laravel 多图上传及图片的存储例子
2019/10/14 PHP
php模拟post提交请求调用接口示例解析
2020/08/07 PHP
js 代码集(学习js的朋友可以看下)
2009/07/22 Javascript
Javascript Request获取请求参数如何实现
2012/11/28 Javascript
Jquery倒数计时按钮setTimeout的实例代码
2013/07/04 Javascript
jQuery中siblings()方法用法实例
2015/01/08 Javascript
使用DNode实现php和nodejs之间通信的简单实例
2015/07/06 NodeJs
Sublime Text 3常用插件及安装方法
2015/12/16 Javascript
深入浅析AngularJS和DataModel
2016/02/16 Javascript
JavaScript开发Chrome浏览器扩展程序UI的教程
2016/05/16 Javascript
BootStrap框架中的data-[ ]自定义属性理解(推荐)
2017/02/14 Javascript
jQuery查找dom的几种方法效率详解
2017/05/17 jQuery
zTree树形插件异步加载方法详解
2017/06/14 Javascript
jQuery接受后台传递的List的实例详解
2017/08/02 jQuery
详解如何使用PM2将Node.js的集群变得更加容易
2017/11/15 Javascript
详解vue使用插槽分发内容slot的用法
2019/03/28 Javascript
小程序实现订单倒计时功能
2019/04/23 Javascript
vue axios post发送复杂对象问题
2019/06/04 Javascript
深入学习TypeScript 、React、 Redux和Ant-Design的最佳实践
2019/06/17 Javascript
vue实现点击追加选中样式效果
2019/11/01 Javascript
VSCode搭建Vue项目的方法
2020/04/30 Javascript
eslint+prettier统一代码风格的实现方法
2020/07/22 Javascript
Vue 事件的$event参数=事件的值案例
2021/01/29 Vue.js
Scrapy框架爬取西刺代理网免费高匿代理的实现代码
2019/02/22 Python
Pycharm 使用 Pipenv 新建的虚拟环境(图文详解)
2020/04/16 Python
python+flask编写一个简单的登录接口
2020/11/13 Python
详解css3使用transform出现字体模糊的解决办法
2020/10/16 HTML / CSS
SQL Server数据库笔试题和答案
2016/02/04 面试题
一些关于MySql加速和优化的面试题
2014/01/30 面试题
甲方资料员岗位职责
2013/12/13 职场文书
《凡卡》教学反思
2014/04/09 职场文书
党建工作整改措施
2014/10/28 职场文书
2014年安全管理工作总结
2014/12/01 职场文书