iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >怎么在python中利用递归实现一个爬虫解析器
  • 708
分享到

怎么在python中利用递归实现一个爬虫解析器

2023-06-14 13:06:56 708人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

怎么在python中利用递归实现一个爬虫解析器?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。另外一种是配置文件预先告知的方式,你配置成什么类型,解析器就通过对应的解析规则去解析

怎么在python中利用递归实现一个爬虫解析器?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

怎么在python中利用递归实现一个爬虫解析器

另外一种是配置文件预先告知的方式,你配置成什么类型,解析器就通过对应的解析规则去解析。

统一网页形式,需要做大量的网页内容形式转换,而配置文件预先告知则需要在配置时指定更多解析字段。相比较而言,通过第二种方式,未来改变较多的是配置规则,不需要动核心代码,引入 bug 的可能性较低。因此这里我们采用第二种方式实现解析器

进一步分析

解析器对于网页内容的提取,本质上和我们在本地电脑上查找和整理文件,没有什么差别。比如像下面这样

怎么在python中利用递归实现一个爬虫解析器

解析内容就是从中提取我们想要的信息,然后整理成我们希望的格式。比如上面的内容,我们提取出来的形式应该是这样

{  "design": "设计图.psd",  "software": "sketch.dmg"}

而在实际的爬虫开发过程中,网页形式远比以上的复杂。其实遇到最多的问题是在一组列表中嵌套一个列表,我们需要把这种形式提取出来。比如像下面这种形式

{    "a": "a",    "b": [        {"c": "c1", "d": "d1"},        {"c": "c2", "d": "d2"}]}

他提取出信息后应该是这样

[  {    "a": "a",    "c": "c1",    "d": "d1"  },  {    "a": "a",    "c": "c2",    "d": "d2"  }]

如果小伙伴对于算法熟悉的话,应该能察觉出这种遍历用递归来写是非常方便的。但要注意的是 Python 会限定递归的层数,小伙伴可以通过下面这个方法查看递归限定的层数

import sysprint(sys.getrecursionlimit())>>>1000

我这边限定的层数是 1k。对于解析网页来说完全够用了,如果哪个人把网页解析逻辑嵌套了 1000 层,我建议你直接跟老板提放弃这个网页吧!

再进一步分析

我们已经知道对于通用解析来说,就是通过配置解析规则提取页面的对应信息。而针对有列表层级的网页可能还涉及递归遍历问题。那如何去配置这种解析规则呢?其实很简单,只需要在进入每一个层级之前先指定该层的数据形式,比如下面这个原数据

{  "a": "a",  "b": [          {"c": "c1", "d": "d1"},          {"c": "c2", "d" : "d2"}       ]}

想提取嵌套信息,我们的解析规则就应该是这样的

[ {  "$name": "a",  "$value_type": "raw",  "$parse_method": "JSON",  "$parse_rule": "a",  "$each": [] }, {  "$name": "__datas__",  "$value_type": "recursion",  "$parse_method": "json",  "$parse_rule": "b",  "$each": [        {           "$name": "c",          "$value_type": "raw",         "$parse_method": "json",         "$parse_rule": "c",         "$each": []        },        {           "$name": "d",          "$value_type": "raw",         "$parse_method": "json",         "$parse_rule": "d",         "$each": []        }      ] }]

其中 $name 字段表示我们最终希望最外层数据所拥有的字段名,当然如果是需要递归到内层的字段,则将列表保存为 __datas__ ,然后根据这个 __datas__ 进行内层结构的解析。最终我们得到的数据结构应该是这样的

[  {"a": "a", "c": "c1", "d": "d1"},   {"a": "a", "c": "c2", "d": "d2"}]

以上我们只演示了 json 的解析规则,如果要拿来解析 html 对象呢?很简单,将解析方式改为 xpath 对象,然后传入 xpath 解析语法即可。

代码实现

总共分成两部分,一部分根据原最终结果和规则进行打包,将所有涉及 recursion 逻辑的字段进行转换,代码如下

def _pack_json(result, rules):        item = {}        for p_rule in rules:            if p_rule.get("$value_type") == "raw":                if p_rule.get("$parse_method") == "json":                    item[p_rule.get("$name")] = glom(result, p_rule.get("$parse_rule"))            elif p_rule.get("$value_type") == "recursion":                if p_rule.get("$parse_method") == "json":                    tmp_result = glom(result, p_rule.get("$parse_rule"))                    total_result = []                    for per_r in tmp_result:                        total_result.append(_pack_json(per_r, p_rule.get("$each")))                    item[p_rule.get("$name")] = total_result        return item

另外一部分将上一步得到的进行解析,将打包得到的结果进行解包,即将所有内嵌的数据提到最外层,代码如下

def _unpack_datas(result: dict) -> list:        if "__datas__" not in result:            return [result]        item_results = []        all_item = result.pop("__datas__")        for per_item in all_item:            if "__datas__" in per_item:                tmp_datas = per_item.pop("__datas__")                for per_tmp_data in tmp_datas:                    tmp_item = _unpack_datas(per_tmp_data)                    for per_tmp_item in tmp_item:                        item_results.append({**per_tmp_item, **per_item})            else:                item_results.append({**result, **per_item})        return item_results

后再包一层执行入口就可以了,完整代码如下

from loguru import loggerfrom glom import glomdef parse(result, rules):    def _pack_json(result, rules):        item = {}        for p_rule in rules:            if p_rule.get("$value_type") == "raw":                if p_rule.get("$parse_method") == "json":                    item[p_rule.get("$name")] = glom(result, p_rule.get("$parse_rule"))            elif p_rule.get("$value_type") == "recursion":                if p_rule.get("$parse_method") == "json":                    tmp_result = glom(result, p_rule.get("$parse_rule"))                    total_result = []                    for per_r in tmp_result:                        total_result.append(_pack_json(per_r, p_rule.get("$each")))                    item[p_rule.get("$name")] = total_result        return item    def _unpack_datas(result: dict) -> list:        if "__datas__" not in result:            return [result]        item_results = []        all_item = result.pop("__datas__")        for per_item in all_item:            if "__datas__" in per_item:                tmp_datas = per_item.pop("__datas__")                for per_tmp_data in tmp_datas:                    tmp_item = _unpack_datas(per_tmp_data)                    for per_tmp_item in tmp_item:                        item_results.append({**per_tmp_item, **per_item})            else:                item_results.append({**result, **per_item})        return item_results    pack_result = _pack_json(result, rules)    logger.info(pack_result)    return _unpack_datas(pack_result)

看完上述内容,你们掌握怎么在python中利用递归实现一个爬虫解析器的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网Python频道,感谢各位的阅读!

--结束END--

本文标题: 怎么在python中利用递归实现一个爬虫解析器

本文链接: https://www.lsjlt.com/news/271108.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么在python中利用递归实现一个爬虫解析器
    怎么在python中利用递归实现一个爬虫解析器?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。另外一种是配置文件预先告知的方式,你配置成什么类型,解析器就通过对应的解析规则去解析...
    99+
    2023-06-14
  • python 用递归实现通用爬虫解析器
    目录需求分析进一步分析再进一步分析代码实现我们在写爬虫的过程中,除了研究反爬之外,几乎全部的时间都在写解析逻辑。那么,生命苦短,为什么我们不写一个通用解析器呢?对啊!为什么不呢?开整...
    99+
    2024-04-02
  • 怎么在python中使用feapde实现一个爬虫
    这篇文章给大家介绍怎么在python中使用feapde实现一个爬虫,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。python是什么意思Python是一种跨平台的、具有解释性、编译性、互动性和面向对象的脚本语言,其最初的...
    99+
    2023-06-14
  • 怎么在python中使用selenium实现一个网络爬虫
    本篇文章为大家展示了怎么在python中使用selenium实现一个网络爬虫,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科...
    99+
    2023-06-08
  • 怎么在hadoop中实现一个java爬虫
    今天就跟大家聊聊有关怎么在hadoop中实现一个java爬虫,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。需要用到Cygwin:一个在windows平台上运行的类UNIX模拟环境,直...
    99+
    2023-05-31
    java ava hadoop
  • 利用java怎么实现一个网页爬虫功能
    利用java怎么实现一个网页爬虫功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。爬虫实现原理网络爬虫基本技术处理网络爬虫是数据采集的一种方法,实际项目开发中,通过爬虫做数...
    99+
    2023-05-31
    java ava
  • 怎么在java中实现一个多线程爬虫
    怎么在java中实现一个多线程爬虫?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java可以用来干什么Java主要应用于:1. web开发;2. Android...
    99+
    2023-06-14
  • C#中怎么实现一个递归树
    这期内容当中小编将会给大家带来有关C#中怎么实现一个递归树,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。C#递归树实现实例:从父结点加字节点,注释的是把字节点向父结点上加//将数据填充到dataTable...
    99+
    2023-06-17
  • node中怎么实现一个http小爬虫
    这篇文章给大家介绍node中怎么实现一个http小爬虫,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。爬取Node.js 教程首页的所有数据建立node-http.js,其中代码如下,代...
    99+
    2024-04-02
  • Java中怎么实现一个网络爬虫
    Java中怎么实现一个网络爬虫,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。首先介绍每个类的功能:DownloadPage.java的功能是下载此超链接的页面源代码.Fun...
    99+
    2023-06-17
  • 怎么在java中利用递归实现二分查找
    本篇文章给大家分享的是有关怎么在java中利用递归实现二分查找,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。Java有哪些集合类Java中的集合主要分为四类:1、List列表:...
    99+
    2023-06-14
  • 在Java中使用Jsoup实现一个爬虫功能
    在Java中使用Jsoup实现一个爬虫功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 Java 爬虫工具Jsoup详解Jsoup是一款 Java 的 HTML 解...
    99+
    2023-05-31
    java 爬虫 jsoup
  • 如何在Python中实现一个简单的爬虫程序
    如何在Python中实现一个简单的爬虫程序随着互联网的发展,数据已成为当今社会最宝贵的资源之一。而爬虫程序则成为了获取互联网数据的重要工具之一。本文将介绍如何在Python中实现一个简单的爬虫程序,并提供具体的代码示例。确定目标网站在开始编...
    99+
    2023-10-22
    Python 程序 爬虫
  • nodejs中怎么实现一个多页面爬虫
    这期内容当中小编将会给大家带来有关nodejs中怎么实现一个多页面爬虫,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。request 用于请求地址和快速下载图片流。 htt...
    99+
    2024-04-02
  • Python爬虫解析器BeautifulSoup4怎么使用
    这篇文章主要介绍“Python爬虫解析器BeautifulSoup4怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python爬虫解析器BeautifulSoup4怎么使用”文章能帮助大家解...
    99+
    2023-07-02
  • 怎么在python中利用merge实现一个堆
    怎么在python中利用merge实现一个堆?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。python有哪些常用库python常用的库:1.requesuts;...
    99+
    2023-06-14
  • c# 中怎么实现一个阶乘递归算法
    c# 中怎么实现一个阶乘递归算法,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。using System;using System.Collections...
    99+
    2023-06-03
  • Vue.js中怎么利用递归组件实现一个可折叠的树形菜单
    本篇文章给大家分享的是有关Vue.js中怎么利用递归组件实现一个可折叠的树形菜单,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。在Vue.js中...
    99+
    2024-04-02
  • 如何在java项目中实现一个递归调用功能
    本篇文章为大家展示了如何在java项目中实现一个递归调用功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现...
    99+
    2023-06-06
  • 怎么在Python中利用tkinter实现一个日期选择器
    这篇文章主要介绍了怎么在Python中利用tkinter实现一个日期选择器,此处通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考价值,需要的朋友可以参考下:首先,定义一个类,叫Calendar# -*- ...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作