Python 网络爬虫:深入解析 Scrapy

        大家好,在当今数字化时代,获取和分析网络数据是许多项目的关键步骤。从市场竞争情报到学术研究,网络数据的重要性越来越被人们所认识和重视。然而,手动获取和处理大量的网络数据是一项繁琐且耗时的任务。幸运的是,Python 的 Scrapy 框架为我们提供了一种强大且高效的解决方案。

        Scrapy 是一个基于 Python 的开源网络爬虫框架,它能够帮助我们快速、高效地抓取和处理网络数据。无论是抓取网页内容、提取结构化数据还是进行数据清洗和分析,Scrapy 都是一种强大的工具。在接下来的内容中,我们将深入探讨 Scrapy 的各个方面,从安装和快速入门开始,逐步介绍其核心组件和高级功能。我们将探讨如何编写 Spider 来定义抓取规则,如何定义 Item 来提取数据,以及如何编写 Pipeline 来处理爬取到的数据。此外,我们还将介绍一些高级用法,如异步处理、用户代理和IP代理、分布式爬取等。

一、介绍

1、什么是 Scrapy?

        Scrapy 是一个基于 Python 的高级网络爬虫框架,用于快速、高效地抓取和处理网页数据。它提供了强大的功能和灵活的架构,使得开发者能够轻松构建和部署自己的网络爬虫。Scrapy 被广泛应用于数据挖掘、搜索引擎、市场分析、学术研究等领域。

2、Scrapy 的主要特点

Scrapy 框架具有许多强大的特点,使其成为首选的网络爬虫工具:

  • 高效性:Scrapy 采用异步处理和多线程机制,能够快速高效地抓取大量网页数据。
  • 灵活性:Scrapy 提供了丰富的配置选项和可扩展的架构,开发者可以根据自己的需求定制和扩展爬虫功能。
  • 智能调度:Scrapy 能够智能调度和管理爬取任务,支持优先级调度、并发控制、下载延迟等策略,确保爬虫的稳定性和效率。
  • 强大的选择器:Scrapy 提供了强大的选择器工具,如 XPath 和 CSS 选择器,方便开发者快速提取目标数据。
  • 数据处理管道:Scrapy 提供了数据处理管道机制,可以方便地对爬取到的数据进行处理、过滤和存储。
  • 分布式支持:Scrapy 支持分布式爬取,可以通过分布式架构提高爬虫的性能和稳定性。

3、安装方法和环境要求

(1)安装方法

Scrapy 可以通过 pip 工具进行安装。在命令行中执行以下命令即可安装最新版本的 Scrapy:

pip install scrapy

(2)环境要求

为了正常安装和运行 Scrapy,需要满足以下环境要求:

  • Python 版本:Scrapy 支持 Python 3.5 及以上版本。
  • 操作系统:Scrapy 可以在 Windows、Linux 和 macOS 等操作系统上运行。
  • 其他依赖:Scrapy 还依赖于一些第三方库,如 Twisted、lxml、pyOpenSSL 等。在安装 Scrapy 时,这些依赖会自动安装。

安装完成后,就可以开始使用 Scrapy 来开发自己的网络爬虫了。

二、快速入门

        在这一部分,将介绍如何快速入门 Scrapy,并通过简单的示例演示如何创建一个新的 Scrapy 项目、编写爬虫 Spider,并运行爬虫来获取网页数据。

1、创建一个新的 Scrapy 项目

        要创建一个新的 Scrapy 项目,可以使用命令行工具 scrapy 提供的 startproject 命令。假设我们要创建一个名为 myproject 的项目,执行以下命令:

scrapy startproject myproject

这将在当前目录下创建一个名为 myproject 的文件夹,其中包含了 Scrapy 项目的基本结构:

myproject/
    scrapy.cfg
    myproject/
        __init__.py
        items.py
        middlewares.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
  • scrapy.cfg:Scrapy 项目的配置文件。
  • myproject/:Scrapy 项目的 Python 包。
  • items.py:定义爬取的数据模型。
  • middlewares.py:定义中间件。
  • pipelines.py:定义数据处理管道。
  • settings.py:Scrapy 项目的设置文件。
  • spiders/:存放爬虫 Spider 的目录。

2、编写爬虫 Spider

        在 spiders/ 目录下,可以创建一个新的 Python 文件来编写爬虫 Spider。假设我们要编写一个简单的 Spider 来抓取某个网站的标题和链接,创建一个名为 example.py 的文件,内容如下:

import scrapy

class ExampleSpider(scrapy.Spider):
    name = 'example'
    start_urls = ['http://example.com']

    def parse(self, response):
        for article in response.css('article'):
            yield {
                'title': article.css('h2::text').get(),
                'link': article.css('a::attr(href)').get(),
            }

        在这个示例中,我们定义了一个名为 ExampleSpider 的 Spider,指定了它的名称为 'example',并指定了起始 URL 为 'http://example.com'。在 parse 方法中,我们使用 CSS 选择器提取了页面中所有的文章标题和链接,并使用 yield 返回抓取到的数据。

3、运行爬虫并查看结果

        要运行刚刚编写的 Spider,可以使用命令行工具 scrapy 提供的 crawl 命令。在项目根目录下执行以下命令:

cd myproject
scrapy crawl example

        这将会启动名为 'example' 的 Spider,并开始抓取数据。抓取完成后,爬取到的数据会默认打印到控制台上。也可以将数据保存到文件或者数据库中,具体可以在 Spider 中自行定义。

三、Scrapy 核心组件

        Scrapy 框架包含了多个核心组件,它们协同工作来完成网络爬虫的各个阶段任务。下面我们将逐一介绍这些核心组件及其用法:

1、Spider

(1)作用和用法:

        Spider 是 Scrapy 框架中最重要的组件之一,用于定义爬虫的行为和抓取规则。每个 Spider 负责从网页中提取数据,并将数据封装为 Item 对象。Spider 需要实现一个或多个爬取网页的方法,通常名为 parse

(2)编写 Spider 的步骤

编写 Spider 的步骤如下:

  1. 创建一个 Spider 类,继承自 scrapy.Spider
  2. 在 Spider 类中定义 name 属性,指定 Spider 的名称。
  3. 在 Spider 类中定义 start_urls 属性,指定起始 URL。
  4. 在 Spider 类中实现 parse 方法,用于解析网页内容并提取数据。

(3)示例

下面是一个简单的示例,展示了如何编写一个 Spider 来抓取网页的标题和链接:

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://example.com']

    def parse(self, response):
        # 提取网页中的标题和链接
        for article in response.css('article'):
            yield {
                'title': article.css('h2::text').get(),
                'link': article.css('a::attr(href)').get(),
            }

        在这个示例中,我们创建了一个名为 MySpider 的 Spider 类,指定了它的名称为 'myspider',并指定了起始 URL 为 'http://example.com'。在 parse 方法中,我们使用 CSS 选择器提取了页面中所有的文章标题和链接,并使用 yield 返回抓取到的数据。 

2、Item

(1)作用和用法:

        Item 是用来定义爬取到的数据的容器,类似于字典。通过定义 Item 类型,可以明确数据的结构,便于后续处理和存储。在 Spider 中提取到的数据可以封装为 Item 对象,然后交给 Pipeline 进行处理。

(2)定义 Item 的步骤

定义 Item 的步骤如下:

  1. 创建一个类,继承自 scrapy.Item
  2. 在类中定义数据字段,字段类型可以是 scrapy.Field 或其子类。

(3)示例

下面是一个简单的示例,展示了如何定义一个 Item 类来存储网页中的标题和链接:

import scrapy

class MyItem(scrapy.Item):
    title = scrapy.Field()
    link = scrapy.Field()

        在这个示例中,我们创建了一个名为 MyItem 的 Item 类,定义了两个字段 titlelink,分别用于存储网页中的标题和链接。这样定义后,我们在 Spider 中抓取到数据后,就可以将数据封装为 MyItem 对象,并交给 Pipeline 进行处理。 

3、Pipeline

(1)作用和用法:

        Pipeline 是用来处理爬取到的数据的组件。当 Spider 提取到数据后,数据会被交给 Pipeline 进行处理,可以进行数据清洗、过滤、验证、存储等操作。Pipeline 可以定义多个,按照优先级依次处理数据。

(2)编写 Pipeline 的步骤

编写 Pipeline 的步骤如下:

  1. 创建一个类,实现 process_item 方法。
  2. process_item 方法中对爬取到的数据进行处理,并返回处理后的数据或者抛出异常。

(3)示例

下面是一个简单的示例,展示了如何编写一个 Pipeline 来处理爬取到的数据并存储到文件中:

class MyPipeline(object):
    def process_item(self, item, spider):
        # 处理爬取到的数据,存储到文件中
        with open('data.txt', 'a', encoding='utf-8') as f:
            f.write(f"{item['title']}, {item['link']}\n")
        return item

        在这个示例中,我们创建了一个名为 MyPipeline 的 Pipeline 类,实现了 process_item 方法。在 process_item 方法中,我们对爬取到的数据进行处理,并将数据存储到文件 'data.txt' 中。最后,我们返回处理后的数据,以便后续的 Pipeline 继续处理或者返回给 Spider。 

4、Middleware

(1)作用和用法:

        Middleware 是 Scrapy 框架的中间件,用于处理请求和响应的过程。它可以在请求被 Spider 处理前和响应被 Spider 处理后对其进行预处理或后处理。Middleware 可以用于修改请求和响应、处理异常、实现代理和用户认证等功能。

(2)编写 Middleware 的步骤

编写 Middleware 的步骤如下:

  1. 创建一个类,实现 process_requestprocess_response 方法。
  2. process_request 方法中对请求进行预处理,然后返回处理后的请求对象。
  3. process_response 方法中对响应进行后处理,然后返回处理后的响应对象。

(3)示例

下面是一个简单的示例,展示了如何编写一个 Middleware 来实现请求和响应的日志记录:

class MyMiddleware(object):
    def process_request(self, request, spider):
        # 在请求被 Spider 处理前进行预处理
        print(f"Processing request: {request.url}")
        return request

    def process_response(self, request, response, spider):
        # 在响应被 Spider 处理后进行后处理
        print(f"Processing response: {response.url}")
        return response

        在这个示例中,我们创建了一个名为 MyMiddleware 的 Middleware 类,实现了 process_requestprocess_response 方法。在 process_request 方法中,我们打印了请求的 URL,在 process_response 方法中,我们打印了响应的 URL。通过这样的方式,我们可以记录请求和响应的信息,方便进行调试和监控。

5、完整示例

        下面是一个简单的示例,演示了如何使用 Scrapy 框架创建一个爬虫,爬取 Quotes to Scrape 网站上的名言,并将结果保存到 JSON 文件中。

import scrapy
from scrapy.crawler import CrawlerProcess

class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = ['http://quotes.toscrape.com']

    def parse(self, response):
        for quote in response.css('div.quote'):
            yield {
                'text': quote.css('span.text::text').get(),
                'author': quote.css('span small::text').get(),
                'tags': quote.css('div.tags a.tag::text').getall(),
            }

        next_page = response.css('li.next a::attr(href)').get()
        if next_page is not None:
            yield response.follow(next_page, self.parse)

# 定义 Scrapy 爬虫的设置
custom_settings = {
    'FEEDS': {'quotes.json': {'format': 'json'}}, # 将结果保存到 quotes.json 文件中
}

# 创建一个 CrawlerProcess 并运行我们的爬虫
process = CrawlerProcess(settings=custom_settings)
process.crawl(QuotesSpider)
process.start()

        运行上述代码,它将从 Quotes to Scrape 网站上抓取名言数据,并将结果保存到 quotes.json 文件中。

四、Scrapy 高级用法

        Scrapy 提供了许多高级功能和技巧,可以帮助你进一步优化和提升爬虫的效率和性能。在这一部分,我们将介绍 Scrapy 的三个高级用法:异步处理、用户代理和 IP 代理、以及分布式爬取。

1、异步处理

异步处理机制:

Scrapy 使用异步处理机制来提高爬取效率。异步处理允许多个操作同时进行,而不会阻塞其他操作。在 Scrapy 中,下载器、中间件和爬虫等组件都是基于 Twisted 框架实现的,利用 Twisted 的事件驱动模型实现了异步处理。

利用异步处理提升爬取效率:

要利用异步处理提升爬取效率,可以注意以下几点:

  • 使用异步请求:Scrapy 默认使用异步请求下载网页,可以同时下载多个网页,提高爬取效率。
  • 使用异步中间件:编写自定义的异步中间件,可以在请求发送和响应处理过程中执行异步操作,如请求重试、代理切换等。
  • 避免阻塞操作:在 Spider 中尽量避免执行阻塞操作,如文件 I/O、数据库查询等,以充分发挥异步处理的优势。

        在 Scrapy 中,默认已经实现了异步处理,但你也可以自定义异步中间件来执行一些异步操作。以下是一个简单的异步中间件示例,用于在请求发送前和响应处理后打印日志:

import scrapy
from twisted.internet.defer import Deferred


class AsyncMiddleware:
    def process_request(self, request, spider):
        # 在请求发送前执行异步操作
        d = Deferred()
        d.addCallback(self.print_log)
        d.callback(request)
        return d

    def process_response(self, request, response, spider):
        # 在响应处理后执行异步操作
        d = Deferred()
        d.addCallback(self.print_log)
        d.callback(response)
        return d

    def print_log(self, result):
        print("Async operation completed:", result)


class MySpider(scrapy.Spider):
    name = 'example'
    start_urls = ['http://example.com']

    def parse(self, response):
        pass

2、用户代理和IP代理

设置用户代理和 IP 代理:

在进行网页抓取时,有些网站会根据请求的用户代理(User-Agent)和 IP 地址来识别爬虫并限制访问。为了规避这些限制,可以设置用户代理和 IP 代理。

常用的用户代理和 IP 代理获取方法:

  • 用户代理:可以在 Spider 中设置 USER_AGENT,也可以使用第三方的用户代理池服务,如 Fake User-Agent、fake-useragent 等。
  • IP 代理:可以使用公开的免费代理,也可以购买付费代理服务,如阿布云、快代理等。

        在 Scrapy 中设置用户代理和 IP 代理可以通过在 Spider 中设置请求头部信息来实现。以下是一个示例,使用随机的用户代理来发送请求:

import scrapy
from scrapy import Request
from fake_useragent import UserAgent

class MySpider(scrapy.Spider):
    name = 'example'
    start_urls = ['http://example.com']

    def parse(self, response):
        # 随机生成用户代理
        user_agent = UserAgent().random
        # 设置请求头部信息
        headers = {'User-Agent': user_agent}
        # 发送请求
        yield Request(url="http://example.com", headers=headers, callback=self.parse_page)

    def parse_page(self, response):
        pass

3、分布式爬取

分布式爬取功能:

Scrapy 支持分布式爬取,可以在多台机器上运行爬虫,并将抓取到的数据统一存储或处理。分布式爬取可以提高爬取速度和效率,同时也增加了系统的可扩展性和稳定性。

利用分布式爬取提高爬取速度和效率:

要利用分布式爬取提高爬取速度和效率,可以采取以下措施:

  • 使用分布式任务调度器:如 scrapy-redis、scrapy-cluster 等,用于在多台机器之间协调任务调度和数据交换。
  • 使用分布式存储和处理:将爬取到的数据存储在分布式数据库或对象存储中,如 MongoDB、Elasticsearch、Hadoop 等,以及使用分布式计算框架进行数据处理和分析。

        要实现分布式爬取,可以使用 Scrapy-Redis 组件。Scrapy-Redis 提供了分布式爬取的支持,可以通过 Redis 来协调多个爬虫节点的任务调度和数据交换。以下是一个简单的示例,展示了如何在 Scrapy-Redis 中配置和使用分布式爬取:

import scrapy
import scrapy_redis

class MySpider(scrapy.Spider):
    name = 'example'
    start_urls = ['http://example.com']

    def parse(self, response):
        pass

# 配置 Scrapy-Redis
REDIS_URL = 'redis://localhost:6379'
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
ITEM_PIPELINES = {
    'scrapy_redis.pipelines.RedisPipeline': 300,
}

# 配置 Redis 连接信息
REDIS_HOST = 'localhost'
REDIS_PORT = 6379

五、常见问题

1、如何处理反爬虫机制?

问题: 部分网站可能会设置反爬虫机制,如限制频繁请求、检测用户代理等,导致爬虫无法正常工作。

解答: 可以采取以下措施应对反爬虫机制:

  • 设置合理的下载延迟和并发量,避免频繁请求。
  • 使用随机的用户代理和 IP 代理,防止被网站识别为爬虫。
  • 使用验证码识别工具或人工识别验证码。
  • 分析网站的反爬虫策略,针对性地调整爬虫策略和参数。

2、如何处理网页内容解析错误?

问题: 在解析网页内容时,可能会遇到 HTML 结构变化、元素定位错误等问题,导致数据提取失败。

解答: 可以采取以下措施应对网页内容解析错误:

  • 使用更加精确的 CSS 选择器或 XPath 表达式来定位元素,避免因页面结构变化导致定位失败。
  • 编写容错处理逻辑,处理解析失败的情况,如设置默认值、捕获异常等。
  • 分析网页结构变化的原因,及时更新爬虫代码以适应新的页面结构。

3、如何处理数据存储和处理错误?

问题: 在数据存储和处理过程中,可能会遇到数据库连接错误、数据格式错误等问题,导致数据丢失或存储失败。

解答: 可以采取以下措施应对数据存储和处理错误:

  • 添加异常处理逻辑,捕获可能出现的异常并进行处理,如重新连接数据库、记录错误日志等。
  • 使用数据验证工具或库,对爬取到的数据进行验证和清洗,保证数据的完整性和准确性。
  • 使用分布式存储和处理方案,将数据存储在多个节点,提高系统的可靠性和稳定性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/672503.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Winform ListView 嵌入组合框、布尔、图片等复杂控件

一、Winform ListView 显示复杂控件示例 以下展示了两种实现思路方案。最后修改日期 2024-05 surfsky 1.1 方案一:ListView 结合组合框进行模拟编辑 基本思路 在界面上放置一个lisview和一个combobox,combobox平时是隐藏的。点击listview&#xff0c…

机械设计手册第一册:公差

形位公差的标注: 形位公差框格中,不仅要表达形位公差的特征项目、基准代号和其他符号,还要正确给出公差带的大小、形状等内容。 1.形位公差框格: 形位公差框格由两个框格或多个格框组成,框格中的主要内容从左到右按…

mysql中基于规则的优化

大家好。我们在平时开发的过程中可能会写一些执行起来十分耗费性能的语句。当MySQL遇到这种sql时会依据一些规则,竭尽全力的把这个很糟糕的语句转换成某种可以比较高效执行的形式,这个过程被称作查询重写,今天我们就来聊一下mysql在查询重写时…

FreeRTOS基础(八):FreeRTOS 时间管理

前面我们用了FreeRTOS中的延时函数,本篇博客就来探讨FreeRTOS中的延时函数,看看他们是如何发挥作用的。当我们在裸机开发中调用delay_ms()函数时,我们的处理器将不处理任何事,造成处理器资源的浪费。 为此,为了提高CPU…

ChatTTS改良版 - 高度逼真的人类情感文本生成语音工具(TTS)本地一键整合包下

先介绍下ChatTTS 和之前发布的 Fish Speech 类似,都是免费开源的文本生成语音的AI软件,但不同的是,ChatTTS测试下来,对于人类情感语调的模仿,应该是目前开源项目做的最好的,是一款高度接近人类情感、音色、…

计算机工作原理(程序猿必备的计算机常识)

目录 一、计算机工作原理1.冯诺依曼体系2. CPU执行指令的过程 二、操作系统三、进程的概念四、进程的管理五、进程的调度 一、计算机工作原理 1.冯诺依曼体系 现在的计算机大多都遵循冯诺依曼体系结构 CPU: 中央处理器,进行算术运算和逻辑判断&#…

百度文心一言API批量多线程写文章软件-key免费无限写

百度文心大模型的两款主力模型ENIRE Speed、ENIRE Lite全面免费,即刻生效。 百度文心大模型的两款主力模型 这意味着,大模型已进入免费时代! 据了解,这两款大模型发布于今年 3 月,支持 8K 和 128k 上下文长度。 ER…

赢销侠的秘密武器:如何提升客户满意度?

在竞争激烈的商业战场上,客户满意度是企业能否长盛不衰的关键。它如同一面镜子,映照出企业的服务质量和产品实力。那么,赢销侠们是如何运用秘密武器来提升客户满意度的呢?本文将深入探讨这一课题,并揭示背后的策略与智…

灾备方案中虚拟化平台元数据备份技术应用

首先需要介绍下元数据是什么? 元数据(Metadata)是一个重要的概念,它描述了数据的数据,也就是说,元数据提供了关于数据属性的信息。这些属性可能包括数据的存储位置、历史数据、资源查找、文件记录等。 元…

LabVIEW与欧陆温控表通讯的实现与应用:厂商软件与自主开发的优缺点

本文探讨了LabVIEW与欧陆温控表通讯的具体实现方法,并对比了使用厂商提供的软件与自行开发LabVIEW程序的优缺点。通过综合分析,帮助用户在实际应用中选择最适合的方案,实现高效、灵活的温控系统。 LabVIEW与欧陆温控表通讯的实现与应用&#…

基于Jenkins+Kubernetes+GitLab+Harbor构建CICD平台

1. 实验环境 1.1 k8s环境 1)Kubernetes 集群版本是 1.20.6 2)k8s控制节点: IP:192.168.140.130 主机名:k8s-master 配置:4C6G 3)k8s工作节点 节点1: IP:192.1…

day-37 最大正方形

思路 动态规划,这题主要得弄明白状态转换方程,dp[i][j]表示以(i,j)为右下角的最大正方形 解题方法 1.首先将第一行和第一列初始化,当对应位置的matrix为’0’时,dp数组对应位置也为零,否则为1 …

上位机图像处理和嵌入式模块部署(f407 mcu中fatfs中间件使用)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们已经实现了spi norflash的驱动,理论上这已经可以实现数据的持久化保存了。为什么还需要一个文件系统呢?主要原因还…

HTML静态网页成品作业(HTML+CSS)——家乡常德介绍网页(1个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有1个页面。 二、作品演示 三、代…

【Qt 学习笔记】Qt窗口 | 对话框 | Qt对话框的分类及介绍

博客主页:Duck Bro 博客主页系列专栏:Qt 专栏关注博主,后期持续更新系列文章如果有错误感谢请大家批评指出,及时修改感谢大家点赞👍收藏⭐评论✍ Qt窗口 | 对话框 | 模态对话框 文章编号:Qt 学习笔记 / 51…

API开发秘籍:揭秘Swagger与Spring REST Docs的文档自动化神技

在这个数字化时代,如何让你的业务像外卖一样快速送达顾客手中?本文将带你走进Spring Boot的世界,学习如何利用RESTful API构建一个高效、直观的“外卖帝国”。从基础的REST架构风格,到Spring MVC的魔力,再到Swagger和S…

解决kettle界面右上角的connect消失——且使用admin登录不上Kettle资源库

一、问题描述 1.1、Kettle界面右上角的connect消失了 当我们配置Kettle界面的资源库(Other Repositories)内容后,Kettle界面右上角的connect消失了;如下图所示: 1.2、使用默认的账户【admin】和密码【admin】登录不上kettle资源库 当我们切换到我们配置的数据库使用超管账…

排序-希尔排序

介绍 希尔排序属于那种没有了解过的直接看代码一脸懵逼的, 所以同学们尽量不要直接看代码,仔细阅读本篇博客内容。 插入排序本来算是一个低效排序, 一次只可以挪动一个数据, 但是,它的强来了!&#xff01…

513.找树左下角的值

给定一个二叉树,在树的最后一行找到最左边的值。 示例 1: 示例 2: 思路: 深度最大的叶子结点一定是最后一行。 优先左边搜索,记录深度最大的叶子节点,此时就是树的最后一行最左边的值 代码: class Solution:def fi…

272 基于matlab的形态滤波和局域值分解(LMD)的齿轮故障诊断

基于matlab的形态滤波和局域值分解(LMD)的齿轮故障诊断,GUI交互界面。通过形态滤波对一维信号进行降噪处理,并通过LMD局部均值分解提取故障信号,最后提取处故障频率。程序已调通,可直接运行。 272 形态滤波…