怎么用python实现精准搜索并提取网页核心内容
这篇文章主要讲解了"怎么用python实现精准搜索并提取网页核心内容",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"怎么用python实现精准搜索并提取网页核心内容"吧!
生成PDF
开始想了一个取巧的方法,就是利用工具(wkhtmltopdf[2])将目标网页生成 PDF 文件。
好处是不必关心页面的具体形式,就像给页面拍了一张照片,文章结构是完整的。
虽然 PDF 是可以源码级检索,但是,生成 PDF 有诸多缺点:
耗费计算资源多、效率低、出错率高,体积太大。
几万条数据已经两百多G,如果数据量上来光存储就是很大的问题。
提取文章内容
不生成PDF,有简单办法就是通过 xpath[3] 提取页面上的所有文字。
但是内容将失去结构,可读性差。更要命的是,网页上有很多无关内容,比如侧边栏,广告,相关链接等,也会被提取下来,影响内容的精确性。
为了保证有一定的结构,还要识别到核心内容,就只能识别并提取文章部分的结构了。像搜索引擎学习,就是想办法识别页面的核心内容。
我们知道,通常情况下,页面上的核心内容(如文章部分)文字比较集中,可以从这个地方着手分析。
于是编写了一段代码,我是用 Scrapy[4] 作为爬虫框架的,这里只截取了其中提取文章部分的代码 :
divs = response.xpath("body//div")sel = Nonemaxvalue = 0for d in divs: ds = len(d.xpath(".//div")) ps = len(d.xpath(".//p")) value = ps - ds if value > maxvalue: sel = { "node": d, "value": value } maxvalue = value print("".join(sel['node'].getall()))response是页面的一个响应,其中包含了页面的所有内容,可以通过xpath提取想要的部分"body//div"的意思是提取所以body标签下的div子标签,注意://操作是递归的遍历所有提取到的标签,计算其中包含的
div数量,和p数量p数量 和div数量的差值作为这个元素的权值,意思是如果这个元素里包含了大量的p时,就认为这里是文章主体通过比较权值,选择出权值最大的元素,这便是文章主体
得到文章主体之后,提取这个元素的内容,相当于 jQuery[5] 的
outerHtml
简单明了,测试了几个页面确实挺好。
不过大量提取时发现,很多页面提取不到数据。仔细查看发现,有两种情况。
有的文章内容被放在了
标签里了,所以没有获取到有的文章每个
外面都包裹了一个,所以p的数量 和div的抵消了再调整了一下策略,不再区分
div,查看所有的元素。另外优先选择更多的
p,在其基础上再看更少的div。调整后的代码如下:divs = response.xpath("body//*")sels = []maxvalue = 0for d in divs: ds = len(d.xpath(".//div")) ps = len(d.xpath(".//p")) if ps >= maxvalue: sel = { "node": d, "ps": ps, "ds": ds } maxvalue = ps sels.append(sel) sels.sort(lambda x: x.ds) sel = sels[0] print("".join(sel['node'].getall()))方法主体里,先挑选出
p数量比较大的节点,注意if判断条件中 换成了>=号,作用时筛选出同样具有p数量的结点经过筛选之后,按照
div数量排序,然后选取div数量最少的
经过这样修改之后,确实在一定程度上弥补了前面的问题,但是引入了一个更麻烦的问题。
就是找到的文章主体不稳定,特别容易受到其他部分有些
p的影响。选择最优
既然直接计算不太合适,需要重新设计一个算法。
我发现,文字集中的地方是往往是文章主体,而前面的方法中,没有考虑到这一点,只是机械地找出了最大的
p。还有一点,网页结构是个颗 DOM 树[6]

那么越靠近
p标签的地方应该越可能是文章主体,也就是说,计算是越靠近p的节点权值应该越大,而远离p的结点及时拥有很多p但是权值也应该小一点。经过试错,最终代码如下:
def find(node, sel): value = 0 for n in node.xpath("*"): if n.xpath("local-name()").get() == "p": t = "".join([s.strip() for s in (n.xpath('text()').getall() + n.xpath("*/text()").getall())]) value += len(t) else: value += find(n, a)*0.5 if value > sel["value"]: sel["node"] = node sel["value"] = value return value sel = { 'value': 0, 'node': None}find(response.xpath("body"), sel)定义了一个
find函数,这是为了方便做递归,第一次调用的参数是body标签,和前面一样进入方法里,只找出该节点的直接孩子们,然后遍历这些孩子
判断如果孩子是
p节点,提取出其中的所有文字,包括子节点的,然后将文字的长度作为权值提取文字的地方比较绕,先取出直接的文本,和间接文本,合成
list,对每部分文本做了去除前后空字符,最后合并为一个字符串,得到了所包含的文本如果孩子节点不是
p,就递归调用find方法,而find方法返回的是 指定节点所包含的文本长度在获取子节点的长度时,做了缩减处理,用以体现距离越远,权值越低的规则
最终通过 引用传递的
sel参数,记录权值最高的节点
通过这样改造之后,效果特别好。
为什么呢?其实利用了密度原理,就是说越靠近中心的地方,密度越高,远离中心的地方密度成倍的降低,这样就能筛选出密度中心了。
50% 的坡度比率是如何得到的呢?
其实是通过实验确定的,刚开始时我设置为 90%,但结果时
body节点总是最优的,因为body里包含了所有的文字内容。反复实验后,确定 50% 是比较好的值,如果在你的应用中不合适,可以做调整。
感谢各位的阅读,以上就是"怎么用python实现精准搜索并提取网页核心内容"的内容了,经过本文的学习后,相信大家对怎么用python实现精准搜索并提取网页核心内容这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
内容 文章 节点 数量 页面 核心 网页 主体 就是 文字 地方 方法 标签 部分 搜索 元素 文本 结构 精准 代码 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全维护工作的公司 广州市海网网络技术有限公司 云数据库的安全问题 软件开发普通人做得来吗 漯河市网络安全周活动 2017网络安全宣传月 非关系型数据库的英文简称 服务器管理软件宝塔提示到期 网络工程网络软件开发难不难 数据库插入数据是注册数据吗 编辑数据库个人总结 康耐得串口设备联网服务器接线 合肥计算机网络技术 网络安全的五禁止是什么 网络安全在我心 艺术字 青浦区本地软件开发诚信合作 数据库数据集表示 双路卷积神经网络技术图片 小度与网络安全 云之端移动互联网科技 几年不得从事网络安全 网络安全和信息化工作任务清单 数据库系统分为几类 读秀数据库一框式检索 Linux启动达蒙数据库 地平线5服务器id为00 战地5怎么进联机服务器 网络安全法研究报告 软件开发加盟代理合作 从服务器获取时间