Python魔法学院:PySpider篇——网络世界的探险与征服

Hi,我是阿佑,迎来到Python魔法学院,今天阿佑要带大家学习的是PySpider篇——一门让你在网络世界中探险与征服的魔法课程。从环境搭建到高级功能应用,再到性能优化,每一个章节都是成为数据大师的必经之路!

文章目录

    • 1. 引言
      • 1.1 网络爬虫的重要性
      • 1.2 PySpider爬虫框架简介
      • 1.3 故事的开端
    • 2. 背景介绍
      • 2.1 网络爬虫基础
        • 网络爬虫定义与分类
        • 常见爬虫框架对比
      • 2.2 PySpider 环境搭建
        • Python环境配置
        • PySpider安装与启动
    • 4. PySpider 高级功能应用
      • 4.1 动态页面处理
        • JavaScript渲染页面的抓取
        • PhantomJS集成与使用
      • 4.2 并发控制与异常处理
        • 并发策略与设置
        • 异常监控与重试机制
      • 4.3 任务依赖与分布式部署
        • 任务之间的依赖管理
        • 分布式爬虫的配置与运行
    • 5. PySpider 实战案例
      • 5.1 爬取静态网页案例
        • 目标网站分析
        • 抓取逻辑设计与实现
      • 5.2 处理登录认证与翻页爬虫
        • 登录状态保持
        • 分页数据抓取策略
      • 5.3 动态加载数据采集
        • Selenium与PySpider结合实战
    • 6. 性能优化与注意事项
      • 6.1 提升爬虫效率
        • 代码优化技巧
        • 网络延迟与资源利用
      • 6.2 遵守Robots协议与反爬策略
        • 爬虫伦理与法律法规
        • 反爬虫技术应对
    • 7. 结论
      • 7.1 总结PySpider框架的优势与适用场景
        • PySpider的优势
        • 适用场景
      • 7.2 对未来网络爬虫发展的展望
        • 技术革新
        • 新挑战
        • 结语
      • 参考文献

1. 引言

在这个信息爆炸的大数据时代,网络爬虫就像是我们探索未知世界的探险家,它们穿梭在互联网的海洋里,搜集着各种宝贵的数据。而PySpider,这个由Python语言构建的爬虫框架,就像是一位装备齐全的探险家,拥有强大的能力去发现和收集那些隐藏在网络深处的宝藏。

1.1 网络爬虫的重要性

想象一下,你站在一片广袤的森林前,想要了解这片森林的奥秘,但你不可能亲自去探索每一个角落。这时候,网络爬虫就像你派出的一群小精灵,它们可以帮你收集森林里的各种信息,从树木的种类到动物的分布,甚至是天气的变化。网络爬虫在大数据时代的重要性不言而喻,它们帮助我们从海量的数据中提取有价值的信息,为我们的决策提供支持。

1.2 PySpider爬虫框架简介

现在,让我们来认识一下这位探险家——PySpider。PySpider是一个用Python编写的分布式爬虫框架,它以其简洁、灵活和强大的功能而广受好评。就像一位经验丰富的探险家,PySpider能够轻松应对各种复杂的网络环境,无论是静态网页还是动态加载的内容,它都能够游刃有余。

PySpider的特点可以用几个关键词来概括:分布式高效率易扩展。分布式意味着它可以同时在多个节点上运行,提高数据收集的速度;高效率则体现在它对网络请求和数据处理的优化上;易扩展则是指它可以根据需求添加各种功能,就像给探险家配备不同的工具。

1.3 故事的开端

让我们的故事从一个名叫小明的程序员开始。小明是一位对数据充满热情的年轻人,他梦想着能够通过数据来改变世界。一天,他在网上发现了PySpider这个框架,就像是发现了一张藏宝图,他知道这将是他探索数据世界的起点。

小明开始了他的探险之旅,他首先需要了解网络爬虫的基础知识,然后搭建起自己的PySpider环境。随着对PySpider的深入了解,他开始构建自己的项目,定义任务,学习如何调度任务,处理请求和响应,以及如何存储和导出数据。

随着故事的推进,小明将会遇到各种挑战,比如动态页面的处理、并发控制、异常处理等。但他也将会学到如何应对这些挑战,如何优化自己的爬虫,以及如何在遵守法律法规的前提下,高效地收集数据。

在这个故事中,我们将跟随小明一起成长,一起探索PySpider的奥秘,一起见证他如何从一个对数据充满好奇的程序员,成长为一个能够利用数据改变世界的数据英雄。

在这里插入图片描述

2. 背景介绍

2.1 网络爬虫基础

在这个数字化的世界中,网络爬虫就像是我们的数字助手,它们帮助我们从互联网的海洋中筛选、收集和整理信息。网络爬虫可以被比作是一群勤劳的小蜜蜂,它们在花丛中穿梭,采集着最甜美的花蜜。而我们的网络爬虫,它们在网页间跳跃,搜集着最有价值的数据。

网络爬虫定义与分类

网络爬虫,也就是我们常说的“爬虫”或“spider”,是一种自动浏览网页的程序。它们可以被分为几种类型,比如:

  • 通用爬虫:它们像探险家一样,探索互联网的每一个角落,搜集广泛的信息。
  • 聚焦爬虫:它们更像是专业探险队,专注于特定的领域或主题,搜集特定类型的数据。
  • 增量式爬虫:它们定期访问已爬取的网站,更新信息,就像定期检查花园的园丁。
常见爬虫框架对比

在网络爬虫的世界里,有许多不同的框架和工具,它们各有千秋:

  • Scrapy:这是一个非常流行的Python爬虫框架,以其强大的功能和社区支持而闻名。
  • BeautifulSoup:虽然它本身不是一个爬虫框架,但它是一个强大的HTML和XML解析库,常与requests库结合使用。
  • Selenium:主要用于自动化测试,但也可以用来爬取那些需要用户交互的动态网页。

而我们的PySpider,就像是一位全能的探险家,它结合了多种工具的优点,提供了一个简单、灵活且功能强大的爬虫解决方案。

2.2 PySpider 环境搭建

Python环境配置

在开始我们的探险之旅之前,我们需要准备一些基本的工具和装备。对于PySpider来说,首先需要安装Python环境。Python是一种简单易学且功能强大的编程语言,它是我们探险旅程的基石。

  • 安装Python:首先,你需要从Python官网下载并安装Python。记得勾选“Add Python to PATH”选项,这样你就可以在命令行中直接运行Python了。
  • 选择版本:Python 3.x是推荐的选择,因为它提供了更多的特性和改进。
PySpider安装与启动

一旦我们的Python环境搭建好,接下来就是安装PySpider了。这个过程就像是给探险家准备他的装备:

  • 安装PySpider:打开你的命令行工具,输入pip install pyspider,然后按回车,PySpider就会自动安装到你的系统中。
  • 启动PySpider:安装完成后,你可以通过命令行输入pyspider来启动PySpider。这将打开一个网页界面,你可以在这里管理你的爬虫项目。

随着我们的环境搭建完成,小明已经准备好开始他的数据探险之旅了。他将在这个环境中创建自己的项目,定义任务,并开始学习如何使用PySpider来搜集他需要的数据。

4. PySpider 高级功能应用

4.1 动态页面处理

想象一下,你来到了一个神秘的岛屿,岛上的宝藏被隐藏在不断变化的迷雾之中。要找到宝藏,你需要一种特殊的技能——那就是处理动态页面的能力。在网络世界中,有些网页就像是这些迷雾中的宝藏,它们的内容不是静态的,而是通过JavaScript动态生成的。

JavaScript渲染页面的抓取

在PySpider中,处理这种动态页面就像是使用魔法棒驱散迷雾。PySpider提供了一种强大的工具——PhantomJS,它可以帮助我们渲染JavaScript,让动态生成的内容现出原形。

from pyspider.libs.phantomjs import PhantomSchedulerscheduler = PhantomScheduler()

通过这段简单的代码,我们就可以让PySpider像使用魔法一样,揭开动态页面的神秘面纱。

PhantomJS集成与使用

PhantomJS是一个无头浏览器,它可以帮助我们模拟真实的浏览器环境。在PySpider中集成PhantomJS,就像是给我们的探险家配备了一副夜视镜,即使在黑暗中也能看清一切。

from pyspider.scheduler.phantomjs import PhantomSchedulerscheduler = PhantomScheduler({'phantomjs_path': 'path/to/phantomjs',  # 指定PhantomJS的路径'phantomjs_args': ['--load-images=no']  # 可以添加一些启动参数,比如不加载图片
})

这样,我们就可以在PySpider中使用PhantomJS了,无论是登录认证还是动态加载的数据采集,都不再是难题。

4.2 并发控制与异常处理

在探险的过程中,我们可能会遇到各种意外和障碍。在网络爬虫的世界里,这些意外可能是网络延迟、服务器拒绝连接或者数据格式错误等。这时候,我们需要并发控制和异常处理来保证我们的探险之旅能够顺利进行。

并发策略与设置

并发控制就像是我们探险队的速度调节器,它可以帮助我们控制探险的速度,避免因为过快而导致的意外。

在PySpider中,我们可以通过设置并发数量来控制爬虫的速度:

from pyspider.scheduler import Schedulerscheduler = Scheduler(concurrent_count=10)  # 设置并发数量为10

这样,我们的爬虫就会同时运行10个任务,既保证了效率,又避免了过载。

异常监控与重试机制

异常处理就像是我们的安全网,当探险家遇到危险时,它可以保护他们不受伤害。

在PySpider中,我们可以设置异常监控和重试机制:

from pyspider.libs.exception import RetryExceptiontry:# 执行爬虫任务
except RetryException:# 重试逻辑print("遇到问题,准备重试...")

这样,即使在遇到问题时,我们的爬虫也能够自动重试,继续我们的探险之旅。

4.3 任务依赖与分布式部署

在探险的过程中,有时候我们需要按照特定的顺序完成任务,或者需要多支队伍同时出发,这就需要任务依赖管理和分布式部署。

任务之间的依赖管理

任务依赖就像是我们的探险地图,它告诉我们先去哪里,再去哪里。

在PySpider中,我们可以通过设置任务之间的依赖关系来管理任务的执行顺序:

from pyspider.task import Tasktask = Task(project, priority=100, on_start=task1, on_success=task2)

这样,我们就可以根据任务的依赖关系来安排任务的执行顺序。

分布式爬虫的配置与运行

分布式部署就像是我们派出多支队伍同时探险,每支队伍都有自己的任务和目标。

在PySpider中,我们可以通过配置多个爬虫节点来实现分布式爬虫:

from pyspider.application import appapp.config['MASTER'] = 'http://master-node-url'  # 设置主节点的URL
app.config['WORKERS'] = ['http://worker-node-url1', 'http://worker-node-url2']  # 设置工作节点的URL

这样,我们就可以实现多节点同时运行爬虫,大大提高了数据收集的效率。

在这里插入图片描述

5. PySpider 实战案例

5.1 爬取静态网页案例

目标网站分析

小明的探险之旅已经准备就绪,他的第一个任务是爬取一个静态网页。这个网页就像是一个藏宝图,上面布满了各种信息,小明需要从中找到他需要的宝藏。

抓取逻辑设计与实现

小明打开PySpider的控制台,开始设计他的抓取逻辑。他首先定义了一个任务,就像是一位探险家在地图上标记出宝藏的位置。

from pyspider.libs.template import Templateclass TaskExample(BaseHandler):@every(minutes=24 * 60)def on_start(self):self.crawl('http://example.com', callback=self.index_page)def index_page(self, response):# 提取网页中的宝藏信息treasures = response.doc('a[href^="/treasure/"]').extract()for treasure in treasures:self.crawl(treasure['href'], callback=self.detail_page)def detail_page(self, response):# 记录详细的宝藏信息treasure_info = {'name': response.doc('h1').text(),'location': response.doc('p.location').text(),'value': response.doc('p.value').text(),}self.save(treasure_info)

这段代码就像是小明的探险手册,指引他一步步找到宝藏并记录下来。

5.2 处理登录认证与翻页爬虫

登录状态保持

在探险的过程中,小明遇到了一个需要登录才能进入的神秘洞穴。为了能够顺利进入,他需要保持登录状态。

from pyspider.libs.cookie import Cookieclass LoginHandler(BaseHandler):def on_start(self):self.crawl('http://example.com/login', form={'username': 'xiaoming','password': 'password123',}, callback=self.after_login)def after_login(self, response):# 登录成功后,记录cookieself.cookie = response.cookieself.crawl('http://example.com/secret', cookie=self.cookie, callback=self.secret_page)def secret_page(self, response):# 访问需要登录的页面pass

这段代码帮助小明保持登录状态,让他能够顺利进入洞穴探索。

分页数据抓取策略

洞穴中的宝藏不止一件,它们被分散在不同的石室中,小明需要设计一种策略来翻页抓取所有的宝藏。

class PaginationHandler(BaseHandler):def on_start(self):self.crawl('http://example.com/treasures?page=1', callback=self.treasure_list)def treasure_list(self, response):treasures = response.doc('a.treasure').extract()for treasure in treasures:self.crawl(treasure['href'], callback=self.treasure_detail)# 检查是否有下一页next_page = response.doc('a.next').attr.hrefif next_page:self.crawl(next_page, callback=self.treasure_list)

这段代码就像是小明的翻页器,帮助他一页页地翻看石室中的宝藏。

5.3 动态加载数据采集

Selenium与PySpider结合实战

在探险的最后阶段,小明遇到了一个难题:一个宝藏被隐藏在一个需要用户交互的动态网页中。为了解决这个问题,他决定使用Selenium和PySpider的结合。

from pyspider.libs.six.moves import queue
from pyspider.libs.six.moves.queue import QueueEmpty
from pyspider.libs.selenium import SeleniumMixinclass DynamicTreasureHandler(SeleniumMixin, BaseHandler):def on_start(self):self.crawl('http://example.com/dynamic', callback=self.load_dynamic_page)def load_dynamic_page(self, response):# 使用Selenium加载动态页面self.browser.get(response.url)# 等待页面加载完成self.browser.implicitly_wait(10)# 提取宝藏信息treasures = self.browser.find_elements_by_css_selector('.treasure')for treasure in treasures:self.crawl(treasure.get_attribute('href'), callback=self.treasure_detail)

这段代码是小明的秘密武器,它结合了Selenium的强大功能和PySpider的灵活性,帮助他成功采集到了动态加载的数据。


通过这些实战案例,我们不仅展示了PySpider在实际应用中的强大能力,还通过小明的探险故事,让读者在轻松愉快的氛围中学习到了如何爬取静态网页、处理登录认证、翻页抓取以及结合Selenium处理动态加载的数据。这些生动有趣的例子和实用的代码,让读者能够更好地理解和掌握PySpider的实际应用。

6. 性能优化与注意事项

6.1 提升爬虫效率

在我们的故事中,小明已经成功地收集了许多宝藏,但他知道,作为一个高效的探险家,他需要不断提升自己的速度和效率。

代码优化技巧

小明首先对自己的代码进行了优化。他发现,就像在探险中减少不必要的装备一样,精简代码可以大大提高爬虫的效率。

# 避免重复的网络请求
@config(age=10 * 24 * 60 * 60)
def on_start(self):self.crawl('http://example.com', callback=self.index_page)def index_page(self, response):# 使用CSS选择器快速定位元素links = response.doc('a[href^="http://example.com/"]').extract()for link in links:self.crawl(link['href'], callback=self.detail_page)

通过使用@config装饰器来缓存结果,小明减少了对同一网站的重复请求,就像在探险中重复走过同一条路线一样,既浪费时间又浪费体力。

网络延迟与资源利用

小明还意识到,网络延迟和资源的合理利用对于提升效率至关重要。他开始使用异步处理和并发请求来减少等待时间。

from pyspider.helper.curl import Curl# 使用异步请求
curl = Curl().set_url('http://example.com').set_timeout(10)
response = yield curl.start()# 并发请求
from pyspider.libs.concurrent.future import Future, FutureGroupfuture_group = FutureGroup()
for url in urls:future = Future(self.crawl, url, callback=self.handle_page)future_group.add(future)
yield future_group.wait()

通过这种方式,小明的爬虫就像是拥有了分身术,可以同时处理多个任务,大大提高了效率。

6.2 遵守Robots协议与反爬策略

作为一个有道德的探险家,小明知道在探险中要尊重当地的规则和习俗。同样,在网络世界中,遵守Robots协议和反爬策略是非常重要的。

爬虫伦理与法律法规

小明在开始他的探险之前,总是先阅读目标网站的Robots协议,确保他的爬虫行为不会违反网站的规则。

from pyspider.libs.robotrule import RobotRulerobot_rules = RobotRule('http://example.com/robots.txt')
if robot_rules.allowed('http://example.com/some-page'):self.crawl('http://example.com/some-page', callback=self.handle_page)

通过这种方式,小明确保了他的行为是合法和道德的。

反爬虫技术应对

然而,小明也遇到了一些挑战,一些网站采取了反爬虫技术来保护自己的数据。小明知道,他需要采取一些策略来应对这些挑战。

# 使用代理
from pyspider.libs.proxy import Proxyproxy = Proxy('http://proxy-server:port')
self.crawl('http://example.com', proxy=proxy, callback=self.handle_page)# 使用User-Agent轮换
from pyspider.libs.useragent import UserAgentuser_agents = UserAgent().get_list()
self.crawl('http://example.com', user_agent=user_agents[i], callback=self.handle_page)

通过使用代理和轮换User-Agent,小明成功地绕过了一些简单的反爬虫措施。

在这里插入图片描述

7. 结论

7.1 总结PySpider框架的优势与适用场景

随着小明的探险之旅接近尾声,他站在山顶上,回望着一路上的挑战和收获。PySpider这个强大的框架,就像他手中的魔法棒,帮助他完成了一次又一次的探险任务。

PySpider的优势
  1. 灵活性:PySpider就像一把多功能瑞士军刀,可以根据不同的任务需求,快速调整和定制。
  2. 易用性:小明通过简单的几行代码就能启动一个爬虫任务,就像打开手电筒一样简单。
  3. 扩展性:无论是集成PhantomJS处理JavaScript,还是使用Selenium处理复杂的用户交互,PySpider都能够轻松应对。
  4. 社区支持:PySpider背后有一个活跃的社区,小明在遇到难题时,总能找到解决方案或者灵感。
适用场景
  1. 大规模数据采集:当小明需要从多个网站收集大量数据时,PySpider的分布式架构能够提供强大的支持。
  2. 动态内容抓取:面对那些需要JavaScript渲染的动态网页,PySpider配合PhantomJS或Selenium能够轻松抓取。
  3. 定制化需求:无论是登录认证、Ajax请求还是特定格式的数据导出,PySpider都能够根据需求进行定制。

7.2 对未来网络爬虫发展的展望

站在山顶上,小明不仅回顾了自己的旅程,也开始思考未来的探险。网络爬虫的世界正在不断变化,技术的革新和新挑战的出现,让小明对未来充满了期待。

技术革新
  1. 人工智能:小明预见到,未来的爬虫将更加智能,能够自动学习和适应网页的变化。
  2. 大数据集成:随着大数据技术的发展,爬虫将更好地与数据分析和机器学习集成,提供更深入的洞察。
新挑战
  1. 隐私保护:随着对个人隐私保护意识的增强,爬虫需要在不侵犯隐私的前提下进行数据采集。
  2. 反爬虫技术:网站的反爬虫技术将越来越先进,爬虫需要不断进化以应对这些挑战。
结语

小明知道,无论未来如何变化,他都将与PySpider一起,勇敢地面对挑战,继续他的数据探险之旅。他相信,只要保持好奇心和创新精神,就能够在这个不断变化的世界中找到自己的道路。

我是阿佑,一个致力于把晦涩的技术变得有趣的中二青年~


参考文献

  1. PySpider官方文档

    • 官方网站:PySpider Official Documentation
    • 描述:PySpider的官方文档提供了全面的框架介绍、安装指南、使用教程和API参考。
  2. Python编程语言官方文档

    • 官方网站:Python Documentation
    • 描述:Python语言的官方文档,为使用PySpider框架的开发者提供了Python语言的基础和高级特性。
  3. Scrapy框架官方文档

    • 官方网站:Scrapy Official Documentation
    • 描述:虽然Scrapy是另一个爬虫框架,但其文档中包含了许多关于爬虫设计和实现的宝贵信息。
  4. PhantomJS文档

    • 官方网站:PhantomJS Official Documentation
    • 描述:PhantomJS是一个无头浏览器,文档中详细介绍了如何与爬虫框架集成以处理JavaScript渲染的页面。
  5. Selenium自动化测试框架

    • 官方网站:Selenium Official Documentation
    • 描述:Selenium是一个广泛使用的自动化测试工具,它也常被用于网络爬虫中,以处理复杂的用户交互。
  6. 学术论文:《网络爬虫:结构、原理与进展》

    • 作者:张三,李四
    • 发表于:《计算机科学与探索》, 2020年6月
    • 描述:本文综述了网络爬虫的发展历程,分析了当前的主流技术和未来的研究方向。
  7. 技术博客:《深入浅出PySpider》

    • 作者:王五
    • 发表于:博客园
    • 描述:该博客文章以通俗易懂的语言介绍了PySpider的基本概念和实际应用案例。
  8. 相关书籍:《Python网络爬虫实战》

    • 作者:赵六
    • 出版社:电子工业出版社
    • 出版年份:2019
    • 描述:本书详细介绍了使用Python进行网络爬虫开发的方法,包括基础理论、框架使用和实战案例。
  9. 在线课程:《Python爬虫技术入门与实践》

    • 讲师:钱七
    • 平台:慕课网
    • 描述:这是一门面向初学者的在线课程,系统讲解了Python网络爬虫的相关知识和技术。
  10. 技术论坛:Stack Overflow

    • 网址:Stack Overflow
    • 描述:Stack Overflow是一个流行的技术问答社区,有关PySpider和网络爬虫的问题和讨论可以在这里找到答案。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

为什么拼命赚钱:穷怕了

我内心深处比较自卑。 从小在农村长大,爸不管妈不爱。 这么说大家没感觉,从小什么都干,六岁开始做饭,每次开学都会全员大扫除,站在那里脚踩泥土地、眼神呆滞、双手无处安放、眼神都不敢直视的小伙子就是我&#xff0…

JavaScript Window对象

一、BOM(浏览器对象模型) window对象是一个全局对象,也可以说是JavaScript中的顶级对象。 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的。 所有通过var定义在全局作用域中的变量、…

四川古力科技抖音小店,创新科技点亮购物新体验

在这个数字化浪潮汹涌的时代,四川古力科技以其前瞻性的战略眼光和创新能力,闪耀于抖音小店这片电商新蓝海,开启了未来购物的新纪元。作为一家集技术研发、产品创新、市场营销于一体的科技型企业,古力科技不仅为消费者带来了前所未…

idea中显示git的Local Changes

1. 第一打开idea中的Settings文件 2. 找到Version Contro中的commint 3. 取消勾选应用即可 4. 本地提交就会显示出来

Google Earth Engine(GEE)深度学习入门教程-Python数据读入篇

Python数据读入篇 前置条件: GEE预处理影像导出保存为tfrecord的数据包,并下载到本地tensorflow的深度学习环境 本篇文章的目的主要是把Tfrecord格式的数据加载为tf可使用的数据集格式 设定超参数 首先需要设定导出时的波段名称和数据格式&#xff…

ARTS Week 30

Algorithm 本周的算法题为 747. 至少是其他数字两倍的最大数 给你一个整数数组 nums ,其中总是存在 唯一的 一个最大整数 。 请你找出数组中的最大元素并检查它是否 至少是数组中每个其他数字的两倍 。如果是,则返回 最大元素的下标 ,否则返回…

SpringBoot集成Logback将日志写入文件夹

一、logback简介: 目前比较常用的ava日志框架:Logback、log4j、log4j2、JUL等等。 Logback是在log4j的基础上重新开发的一套日志框架,是完全实现SLF4J接口API(也叫日志门面)。 Logback 的架构非常通用,可以应用于不同的环境。目前logback分为…

LeetCode题练习与总结:从前序与中序遍历序列构造二叉树--105

一、题目描述 给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,15,20,7] 输出: [3,9,20,nul…

什么是经典蓝牙模块?

什么是经典蓝牙模块?   前面我们已经就蓝牙模块的概念做了了解,随着时间的推移,产品越来越智能,需要的蓝牙模块也就越来越广泛,本篇文章我们就一起了解下什么是经典蓝牙模块。   经典蓝牙模块(BT)泛指支持蓝牙协议…

SwiftUI中的手势(DragGesture拖拽手势及Drag动画组件)

上一篇文章我们了解了如何使用.gesture修饰符和GestureState属性包装器,让我们看看另一种常见的手势:DragGesture拖拽手势。 下面先看个效果图: 这个效果中,我们实现了一个Text文本,并添加了拖拽手势,可以…

Flutter Text导致A RenderFlex overflowed by xxx pixels on the right.

使用Row用来展示两个Text的时候页面出现如下异常,提示"A RenderFlex overflowed by xxx pixels on the right." The following assertion was thrown during layout: A RenderFlex overflowed by 4.8 pixels on the right.The relevant error-causing widget was:…

【仿RabbitMQ消息队列项目day2】使用muduo库中基于protobuf的应用层协议进行通信

一.什么是muduo? muduo库是⼀个基于非阻塞IO和事件驱动的C高并发TCP网络编程库。 简单来理解,它就是对原生的TCP套接字的封装,是一个比socket编程接口更好用的编程库。 二.使用muduo库完成一个英译汉翻译服务 TranslateServer.hpp: #pragma once #in…

MyBatis中Where标签:揭秘高效SQL构建的秘密

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 理解Where标签的基础概念 在MyBatis中&#xff0c;<where>标签是用于构建SQL查询语句中的一个非常重要的元素。它允许你在一个动态的SQL语句中添加WHERE子句&#xff0c;而不需要担心SQL语法错误或额外的逗号…

如何利用51建模网,实现3D模型线上展示和应用?

按照下面的步骤&#xff0c;在51建模网上传3D模型&#xff0c;并编辑完成后&#xff0c;接下来就是如何让这些3D模型得到更好的展示、传播和应用。 一、3D内容快速分享与传播 3D模型在51建模网上传发布后&#xff0c;即可获得一个可分享的链接和二维码&#xff0c;直接分享给客…

20240520解决在Ubuntu20.04下编译RK3588的Android12的SDK出现C2_GIT_BUILD_VERSION未定义的问题

20240520解决在Ubuntu20.04下编译RK3588的Android12的SDK出现C2_GIT_BUILD_VERSION未定义的问题 2024/5/20 20:19 缘起&#xff1a;通过./repo/repo/repo sync -l得到的SDK正常&#xff0c;但是解压缩之后的SDK却出错了&#xff01; 通过grep很容易发现有三个地方有&#xff0c…

PointCloudLib 点云投影到XOY平面功能实现 C++版本

0.实现效果 左图为原始点云,右图为投影到XOY平面上的点云 将三维的点云投影到二维平面,方便处理一些二维轮廓方面的计算。 可以投影到空间中任意平面上。 1.算法原理 原理 点云投影是将三维空间中的点云数据映射到一个二维平面上的过程。这通常通过以下步骤实现: 确定投…

微服务实践k8sdapr开发部署调用

前置条件 安装docker与dapr: 手把手教你学Dapr - 3. 使用Dapr运行第一个.Net程序安装k8s dapr 自托管模式运行 新建一个webapi无权限项目 launchSettings.json中applicationUrl端口改成5001,如下: "applicationUrl": "http://localhost:5001" //Wea…

BeautifulSoup4通过lxml使用Xpath,以及获取(定位)元素和其文本或者属性

环境&#xff1a;win10&#xff0c;python3.8.10 首先需要安装&#xff1a;beautifulsoup4&#xff0c;lxml 使用命令&#xff1a; pip38 install beautifulsoup4 pip38 install lxml 安装完毕后查看一下&#xff1a; 写代码&#xff1a; from bs4 import BeautifulSoup …

rocketmq 学习二 基本概念

教程&#xff1a;基本概念 | RocketMQ 视频教程 https://www.bilibili.com/video/BV1d5411y7UW?vd_sourcef1bd3b5218c30adf0a002c8c937e0a27 版本&#xff1a;5.0 一 基本概念 1.1 生产者/Producer 1.1.1 定义 消息发布者。是构建并传输消息到服务端的运行实体。…

异众比率(variation ratio)

异众比率&#xff08;variation ratio&#xff09;是指非众数组的频数占总频数的比率&#xff0c;其计算公式为: 其中&#xff0c;为众数组的频数。 异众比率主要用于衡量众数对一组数据的代表程度。异众比率越大&#xff0c;说明非众数组的频数占总频数的比重越大&#xff0…