深度剖析使用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脚本快速为iOS10生成图标和截屏
Sep 22 Python
Python 错误和异常代码详解
Jan 29 Python
python实现输入数字的连续加减方法
Jun 22 Python
python处理multipart/form-data的请求方法
Dec 26 Python
一篇文章了解Python中常见的序列化操作
Jun 20 Python
Django Python 获取请求头信息Content-Range的方法
Aug 06 Python
Python实现决策树并且使用Graphviz可视化的例子
Aug 09 Python
pandas to_excel 添加颜色操作
Jul 14 Python
Python绘图之二维图与三维图详解
Aug 04 Python
python 星号(*)的多种用途
Sep 21 Python
django使用多个数据库的方法实例
Mar 04 Python
使用qt quick-ListView仿微信好友列表和聊天列表的示例代码
Jun 13 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
推荐几个开源的微信开发项目
2014/12/28 PHP
ThinkPHP中create()方法自动验证表单信息
2017/04/28 PHP
PHP开发API接口签名生成及验证操作示例
2020/05/27 PHP
javascript css float属性的特殊写法
2008/11/13 Javascript
js调用后台、后台调用前台等方法总结
2014/04/17 Javascript
JavaScript合并两个数组并去除重复项的方法
2015/06/13 Javascript
jquery读写cookie操作实例分析
2015/12/24 Javascript
jQuery simplePage+AJAX plus分页插件用法实例
2016/02/17 Javascript
详解Javascript继承的实现
2016/03/25 Javascript
微信公众平台开发教程(四) 实例入门:机器人回复(附源码)
2016/12/02 Javascript
jQuery Ajax 实现在html页面实时显示用户登录状态
2016/12/30 Javascript
基于jquery二维码生成插件qrcode
2017/01/07 Javascript
AngularJs每天学习之总体介绍
2017/08/07 Javascript
在 Angular 中使用Chart.js 和 ng2-charts的示例代码
2017/08/17 Javascript
Angular4开发解决跨域问题详解
2017/08/28 Javascript
react-redux中connect的装饰器用法@connect详解
2018/01/13 Javascript
在Vue项目中引入腾讯验证码服务的教程
2018/04/03 Javascript
JS实现根据指定值删除数组中的元素操作示例
2018/08/02 Javascript
jQuery 获取除某指定对象外的其他对象 ( :not() 与.not())
2018/10/10 jQuery
javascript中如何判断类型汇总
2019/05/14 Javascript
no-vnc和node.js实现web远程桌面的完整步骤
2019/08/11 Javascript
jQuery实现动态加载瀑布流
2020/09/01 jQuery
vue v-model的用法解析
2020/10/19 Javascript
[01:19:54]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#1Alliance VS EHOME
2016/03/03 DOTA
[00:16]热血竞技场
2019/03/06 DOTA
python中的json总结
2018/10/11 Python
Python2和Python3之间的str处理方式导致乱码的讲解
2019/01/03 Python
Python交互式图形编程的实现
2019/07/25 Python
浅析Python+OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估
2019/10/17 Python
Python接口自动化判断元素原理解析
2020/02/24 Python
使用Python快速打开一个百万行级别的超大Excel文件的方法
2021/03/02 Python
学习经验演讲稿
2014/05/10 职场文书
汽车服务工程专业自荐信
2014/09/02 职场文书
见习报告格式要求
2014/11/04 职场文书
小学母亲节活动总结
2015/02/10 职场文书
2015年女职工工作总结
2015/05/15 职场文书