深度剖析使用python抓取网页正文的源码
本方法是基于文本密度的方法,最初的想法来源于哈工大的《基于行块分布函数的通用网页正文抽取算法》,本文基于此进行一些小修改。
约定:
本文基于网页的不同行来进行统计,因此,假设网页内容是没有经过压缩的,就是网页有正常的换行的。
有些新闻网页,可能新闻的文本内容比较短,但其中嵌入一个视频文件,因此,我会给予视频较高的权重;这同样适用于图片,这里有一个不足,应该是要根据图片显示的大小来决定权重的,但本文的方法未能实现这一点。
由于广告,导航这些非正文内容通常以超链接的方式出现,因此文本将给予超链接的文本权重为零。
这里假设正文的内容是连续的,中间不包含非正文的内容,因此实际上,提取正文内容,就是找出正文内容的开始和结束的位置。
步骤:
首先清除网页中CSS,Javascript,注释,Meta,Ins这些标签里面的内容,清除空白行。
计算每一个行的经过处理的数值(1)
计算上面得出的每行文本数的最大正子串的开始结束位置
其中第二步需要说明一下:
对于每一行,我们需要计算一个数值,这个数值的计算如下:
一个图片标签img,相当于出现长度为50字符的文本(给予的权重),x1,
一个视频标签embed,相当于出现长度为1000字符的文本,x2
一行内所有链接的标签a的文本长度x3,
其他标签的文本长度x4
每行的数值=50*x1其出现次数+1000*x2其出现次数+x4?8
//说明,-8因为我们要计算一个最大正子串,因此要减去一个正数,至于这个数应该多大,我想还是按经验来吧。
完整代码
#coding:utf-8
importre
defremove_js_css(content):
"""removethethejavascriptandthestylesheetandthecommentcontent(<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)
returns
defremove_empty_line(content):
"""removemultispace"""
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)
returns
defremove_any_tag(s):
s=re.sub(r"""<[^>]+>""","",s)
returns.strip()
defremove_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)
returnlen("".join(text)),len(text_b)
defremove_image(s,n=50):
image="a"*n
r=re.compile(r"""<img.*?>""",re.I|re.M|re.S)
s=r.sub(image,s)
returns
defremove_video(s,n=1000):
video="a"*n
r=re.compile(r"""<embed.*?>""",re.I|re.M|re.S)
s=r.sub(video,s)
returns
defsum_max(values):
cur_max=values[0]
glo_max=-999999
left,right=0,0
forindex,valueinenumerate(values):
cur_max+=value
if(cur_max>glo_max):
glo_max=cur_max
right=index
elif(cur_max<0):
cur_max=0
foriinrange(right,-1,-1):
glo_max-=values[i]
ifabs(glo_max<0.00001):
left=i
break
returnleft,right+1
defmethod_1(content,k=1):
ifnotcontent:
returnNone,None,None,None
tmp=content.split("\n")
group_value=[]
foriinrange(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)
returnleft,right,len("\n".join(tmp[:left])),len("\n".join(tmp[:right]))
defextract(content):
content=remove_empty_line(remove_js_css(content))
left,right,x,y=method_1(content)
return"\n".join(content.split("\n")[left:right])
代码从最后一个函数开始调用。
相关文章
- origin安装嵌入python_python爬虫之git的使用(origin说明)
- python字符串转化列表_Python列表到字符串的转换[通俗易懂]
- python编程是什么-Python编程
- python jieba库_Python jieba库的使用说明「建议收藏」
- Python入门系列(六)一篇学会python函数
- Python爬虫:逆向分析某酷音乐请求参数
- python判断linux中文件是否存在_Python判断文件是否存在的三种方法
- 符合python命名规范的标识符是什么_Python标识符命名规范
- python进阶(6)深拷贝和浅拷贝「建议收藏」
- python打开网页链接_怎么用python打开浏览器
- 【说站】python默认索引是什么
- 【说站】Python位置索引的介绍
- 【说站】python if-elif-else语句是什么
- python分析人口出生率代码_国家统计局居然也能用的上Python?人口数据Python脚本了解一下?…[通俗易懂]
- 关于python中lambda函数的描述_Python全局变量
- Python之服务巡检
- 如何用 Python 的 dataclass 和 typing 模块实现字段 tag 功能
- python实现微信不断给好友发消息
- 写【Python折线图】的一百个技巧(一、生成折线图网页)
- 软件测试|Python内置模块使用(一)
- 用Python Django建一个issue跟踪管理网站(一)Django的安装和使用
- Python的下载、安装、配置环境变量详解程序员
- 搞定!Linux下快速设置Python环境变量(linux设置python环境变量)
- python的tqdm模块介绍详解编程语言
- 运维学python之爬虫基础篇(一)开篇
- 在Python中简单调用MySQL(python调用mysql)
- Python字符转换
- Python高效编程技巧
- python文件比较示例分享
- python改变日志(logging)存放位置的示例
- Python操作json数据的一个简单例子
- Python使用PyGreSQL操作PostgreSQL数据库教程