怎么用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安全错误 数据库的锁怎样保障安全 广州万易互联网科技有限公司 山东特亿宝互联网科技有限公司 没上市的科技互联网公司 奇酷互联网科技公司 世界互联网领先科技成果 贷财互联网科技 赫美联合互联网科技 互联网科技小额贷款 济南和联互联网科技有限公司 玖二柒互联网科技公司待遇 北京三清互联网科技 互联网科技中介 互联网校园科技培训 互联网与医疗科技 南博望互联网科技有限公司 互联网企业科技类企业如何做账 北京市互联网新科技 互联网时代高科技布局 网互联网络科技 恒生科技互联网指数十大成分股 新华互联网科技学校 互联网科技有限公司经营范围 善班互联网科技有限公司 润盈互联网科技 银川新华互联网科技学校地址 和信科技工业互联网 开一家科技互联网公司需要多少钱 雨阳互联网卡科技有限公司 北京品多多互联网科技有限公司 互联网 科技节活动 微视频大赛