vb抓取网页内容(如何识别页面的核心内容[4]作为一种怎样的体验)

优采云 发布时间: 2021-11-01 11:03

  vb抓取网页内容(如何识别页面的核心内容[4]作为一种怎样的体验)

  目录选择的最佳总结

  

  正文|李小飞

  来源:Python技术《ID:pythonall》

  每个人都必须熟悉爬虫程序。随便写一个获取网页信息,甚至通过请求自动生成Python脚本[1]。

  最近在网上遇到一个爬虫项目,需要爬取文章。感觉没什么特别的,但是问题是没有抓取范围的限制,也就是说没有清晰的页面结构。

  对于一个页面来说,除了核心的文章内容,还有head、tail、左右列表列等等。有的页框使用div布局,有的使用table。即使两者都使用div,less网站的样式和布局是不同的。

  但问题必须解决。我想,既然搜索引擎已经抓取了各种网页的核心内容,我们应该也能应付。拿起 Python 去做吧!

  各种尝试

  如何解决?

  生成PDF

  我开始想到一个棘手的方法,就是使用工具(wkhtmltopdf[2])生成目标网页的PDF文件。

  好处是不需要关心页面的具体形式,就像给页面拍照一样,文章结构完整。

  虽然可以在源码级别检索PDF,但是生成PDF有很多缺点:

  计算资源消耗大,效率低,错误率高,体积过大。

  数以万计的数据已超过两百千兆字节。如果数据量达到存储,那将是一个大问题。

  提取 文章 内容

  有一种简单的方法可以通过 xpath[3] 提取页面上的所有文本,而不是生成 PDF。

  但是内容会失去结构,可读性会很差。更糟糕的是,网页上还有很多不相关的内容,比如侧边栏、广告、相关链接等,也会被提取出来,影响内容的准确性。

  为了保证一定的结构和识别核心内容,只能识别和提取文章部分的结构。像搜索引擎一样学习,就是想办法识别页面的核心内容。

  我们知道,一般情况下,页面的核心内容(比如文章部分)文字比较集中,可以从这个地方开始分析。

  于是写了一段代码,我用Scrapy[4]作为爬虫框架,这里只截取了提取文章部分的代码:

  

divs = response.xpath("body//div")

sel = None

maxvalue = 0

for 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()))

  简单明了,测试几页真的很好。

  但是,在提取大量页面时,发现很多页面无法提取数据。仔细一看,发现有两种情况。

  再次调整策略,不再区分div,查看所有元素。

  另外,更喜欢p,然后在此基础上看更少的div。调整后的代码如下:

  

divs = response.xpath("body//*")

sels = []

maxvalue = 0

for 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的影响。

  选最好的

  由于不适合直接计算,需要重新设计算法。

  发现文字集中的地方往往是文章的主体。前面的方法没有考虑这个,而是机械地找到最大的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)

  经过这次改造,效果特别好。

  为什么?其实就是利用了密度原理,即离中心越近,密度越高,离中心越远,密度呈指数下降,这样就可以滤除密度中心。

  50%的斜率是如何得到的?

  其实是通过实验确定的。一开始,我把它设置为90%,但结果是body节点总是最好的,因为body收录了所有的文本内容。

  经过反复实验,确定 50% 是一个更好的值。如果它不适合您的应用程序,您可以进行调整。

  总结

  在描述了我如何选择文章 主题的方法后,我没有意识到它实际上是一个非常简单的方法。而这次解题的经历,让我感受到了数学的魅力。

  我一直认为,只要理解了常规的处理问题的方式,处理日常编程就足够了。当遇到不确定的问题,又没有办法提取出简单的问题模型时,常规思维显然是不行的。

  因此,我们通常应该看看一些数学上很强的方法来解决不确定的问题,以提高我们的编程适应性,扩大我们的技能范围。

  我希望这篇短文能给你带来启发。欢迎在留言区交流讨论,大展身手!

  参考

  [1]

  卷曲到 Python:

  [2]

  wkhtmltopdf:

  [3]

  路径:

  [4]

  刮痧:

  [5]

  jQuery:

  [6]

  DOM 树:%20Tree/6067246

  以上就是python实现精准搜索和提取网页核心内容的详细过程。关于python搜索和提取网页内容的更多信息,请关注云海天教程和其他相关文章!

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线