深度剖析使用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中将字典转换为列表的方法
Sep 21 Python
python僵尸进程产生的原因
Jul 21 Python
python获取外网IP并发邮件的实现方法
Oct 01 Python
Python cookbook(数据结构与算法)找出序列中出现次数最多的元素算法示例
Mar 15 Python
python实现批量修改图片格式和尺寸
Jun 07 Python
python3结合openpyxl库实现excel操作的实例代码
Sep 11 Python
彻彻底底地理解Python中的编码问题
Oct 15 Python
Python中最大递归深度值的探讨
Mar 05 Python
Pycharm debug调试时带参数过程解析
Feb 03 Python
Python基于requests实现模拟上传文件
Apr 21 Python
Pytorch 卷积中的 Input Shape用法
Jun 29 Python
pycharm 多行批量缩进和反向缩进快捷键介绍
Jan 15 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
超级简单的发送邮件程序
2006/10/09 PHP
php中读写文件与读写数据库的效率比较分享
2013/10/19 PHP
Discuz!X中SESSION机制实例详解
2015/09/23 PHP
详解WordPress开发中过滤属性以及Sql语句的函数使用
2015/12/25 PHP
PHP 面向对象程序设计之类属性与类常量实现方法分析
2020/04/13 PHP
JQUERY 实现窗口滚动搜索框停靠效果(类似滚动停靠)
2013/03/27 Javascript
javascript闭包传参和事件的循环绑定示例探讨
2014/04/17 Javascript
简介JavaScript中toTimeString()方法的使用
2015/06/12 Javascript
jQuery动画效果实现图片无缝连续滚动
2016/01/12 Javascript
微信小程序 特效菜单抽屉效果实例代码
2017/01/11 Javascript
详解Node.js中exports和module.exports的区别
2017/04/19 Javascript
微信小程序中hidden不生效原因的解决办法
2017/04/26 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
protractor的安装与基本使用教程
2017/07/07 Javascript
基于复选框demo(分享)
2017/09/27 Javascript
vue实现点击隐藏与显示实例分享
2019/02/13 Javascript
vue多层嵌套路由实例分析
2019/03/19 Javascript
微信小程序实现页面分享onShareAppMessage
2019/08/12 Javascript
js观察者模式的弹幕案例
2020/11/23 Javascript
[44:09]DOTA2上海特级锦标赛A组小组赛#1 EHOME VS MVP.Phx第二局
2016/02/25 DOTA
Django1.7+python 2.78+pycharm配置mysql数据库
2016/10/09 Python
python 删除大文件中的某一行(最有效率的方法)
2017/08/19 Python
利用python3随机生成中文字符的实现方法
2017/11/24 Python
Python模拟简单电梯调度算法示例
2018/08/20 Python
win10下python3.5.2和tensorflow安装环境搭建教程
2018/09/19 Python
python 利用浏览器 Cookie 模拟登录的用户访问知乎的方法
2019/07/11 Python
1688平价精选商城:阿里集团旗下,工厂出厂价格直销
2017/04/24 全球购物
捷克鲜花配送:Florea.cz
2018/10/29 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
工作失职检讨书500字
2014/10/17 职场文书
初中生思想道德自我评价
2015/03/09 职场文书
战马观后感
2015/06/08 职场文书
幼儿园2016年圣诞活动总结
2016/03/31 职场文书
一次MySQL启动导致的事故实战记录
2021/09/15 MySQL
MySQL创建定时任务
2022/01/22 MySQL
Web应用开发TypeScript使用详解
2022/05/25 Javascript