【python爬虫】14.Scrapy框架讲解

文章目录

  • 前言
  • Scrapy是什么
    • Scrapy的结构
    • Scrapy的工作原理
  • Scrapy的用法
    • 明确目标与分析过程
    • 代码实现——创建项目
    • 代码实现——编辑爬虫
    • 代码实现——定义数据
    • 代码实操——设置
    • 代码实操——运行
  • 复习

前言

前两关,我们学习了能提升爬虫速度的进阶知识——协程,并且通过项目实操,将协程运用于抓取薄荷网的食物数据。

可能你在体验开发一个爬虫项目的完整流程时,会有这样的感觉:原来要完成一个完整的爬虫程序需要做这么多琐碎的工作。

比如,要导入不同功能的模块,还要编写各种爬取流程的代码。而且根据不同的项目,每次要编写的代码也不同。

不知道你会不会有这样的想法:能不能有一个现成的爬虫模板,让我们拿来就能套用,就像PPT模板一样。我们不需要管爬虫的全部流程,只要负责填充好爬虫的核心逻辑代码就好。要是有的话,我们编写代码一定会很方便省事。

其实,在Python中还真的存在这样的爬虫模板,只不过它的名字是叫框架。

一个爬虫框架里包含了能实现爬虫整个流程的各种模块,就像PPT模板一开始就帮你设置好了主题颜色和排版方式一样。

这一关,我们要学习的就是一个功能强大的爬虫框架——Scrapy。

Scrapy是什么

以前我们写爬虫,要导入和操作不同的模块,比如requests模块、gevent库、csv模块等。而在Scrapy里,你不需要这么做,因为很多爬虫需要涉及的功能,比如麻烦的异步,在Scrapy框架都自动实现了。

我们之前编写爬虫的方式,相当于在一个个地在拼零件,拼成一辆能跑的车。而Scrapy框架则是已经造好的、现成的车,我们只要踩下它的油门,它就能跑起来。这样便节省了我们开发项目的时间。

在这里插入图片描述
下面,我们来了解Scrapy的基础知识,包括Scrapy的结构及其工作原理。

Scrapy的结构

在这里插入图片描述
上面的这张图是Scrapy的整个结构。你可以把整个Scrapy框架看成是一家爬虫公司。最中心位置的Scrapy Engine(引擎)就是这家爬虫公司的大boss,负责统筹公司的4大部门,每个部门都只听从它的命令,并只向它汇报工作。

我会以爬虫流程的顺序来依次跟你介绍Scrapy爬虫公司的4大部门。

Scheduler(调度器)部门主要负责处理引擎发送过来的requests对象(即网页请求的相关信息集合,包括params,data,cookies,request headers…等),会把请求的url以有序的方式排列成队,并等待引擎来提取(功能上类似于gevent库的queue模块)。

Downloader(下载器)部门则是负责处理引擎发送过来的requests,进行网页爬取,并将返回的response(爬取到的内容)交给引擎。它对应的是爬虫流程【获取数据】这一步。

Spiders(爬虫)部门是公司的核心业务部门,主要任务是创建requests对象和接受引擎发送过来的response(Downloader部门爬取到的内容),从中解析并提取出有用的数据。它对应的是爬虫流程【解析数据】和【提取数据】这两步。

Item Pipeline(数据管道)部门则是公司的数据部门,只负责存储和处理Spiders部门提取到的有用数据。这个对应的是爬虫流程【存储数据】这一步。

Downloader Middlewares(下载中间件)的工作相当于下载器部门的秘书,比如会提前对引擎大boss发送的诸多requests做出处理。

Spider Middlewares(爬虫中间件)的工作则相当于爬虫部门的秘书,比如会提前接收并处理引擎大boss发送来的response,过滤掉一些重复无用的东西。

在这里插入图片描述

Scrapy的工作原理

你会发现,在Scrapy爬虫公司里,每个部门都各司其职,形成了很高效的运行流程。

这套运行流程的逻辑很简单,就是:引擎大boss说的话就是最高需求。

在这里插入图片描述
上图展现出的也是Scrapy框架的工作原理——引擎是中心,其他组成部分由引擎调度。

在Scrapy里,整个爬虫程序的流程都不需要我们去操心,且Scrapy中的程序全部都是异步模式,所有的请求或返回的响应都由引擎自动分配去处理。

哪怕有某个请求出现异常,程序也会做异常处理,跳过报错的请求,继续往下运行程序。

在一定程度上,Scrapy可以说是非常让人省心的一套爬虫框架。

Scrapy的用法

现在,你已经初步了解Scrapy的结构以及工作原理。接下来,为了让你熟悉Scrapy的用法,我们使用它来完成一个小项目——爬取豆瓣Top250图书。

在这里插入图片描述

明确目标与分析过程

依旧是遵循写代码的三个步骤:明确目标、分析过程、代码实现来完成项目。我会在代码实现的步骤重点讲解Scrapy的用法。

首先,要明确目标。请你务必打开以下豆瓣Top250图书的链接。

https://book.douban.com/top250

豆瓣Top250图书一共有10页,每页有25本书籍。我们的目标是:先只爬取前三页书籍的信息,也就是爬取前75本书籍的信息(包含书名、出版信息和书籍评分)。

接着,我们来分析网页。既然我们要爬取书籍信息,我们就得先判断这些信息被存在了哪里。

判断的方法你应该了然于胸。赶紧右击打开“检查”工具,点开Network,刷新页面,然后点击第0个请求top250,看Response.

我们能在里面翻找到书名、出版信息,说明我们想要的书籍信息就藏在这个网址的HTML里。

在这里插入图片描述
确定书籍信息有存在这个网址的HTML后,我们就来具体观察一下这个网站。

你点击翻到豆瓣Top250图书的第2页。

在这里插入图片描述
你会观察到,网址发生了变化,后面多了?start=25。我们猜想,后面的数字是代表一页的25本书籍。

你可以翻到第3页,验证一下我们的猜想是不是正确的。

在这里插入图片描述
事实证明,我们猜对了。每翻一页,网址后面的数字都会增加25,说明这个start的参数就是代表每页的25本书籍。

这么一观察,我们要爬取的网址的构造规律就出来了。只要改变?start=后面的数字(翻一页加25),我们就能得到每一页的网址。

找到了网址的构造规律,我们可以重点来分析HTML的结构,看看等下怎么才能提取出我们想要的书籍信息。

仍旧是右击打开“检查”工具,点击Elements,再点击光标,把鼠标依次移到书名、出版信息、评分处,就能在HTML里找到这些书籍信息。如下图,《追风筝的人》的书籍信息就全部放在<table width="100%">标签里。

在这里插入图片描述

很快,你就会发现,其实每一页的25本书籍信息都分别藏在了一个<table width="100%">标签里。不过这个标签没有class属性,也没有id属性,不方便我们提取信息。

在这里插入图片描述
我们得再找一个既方便我们提取,又能包含所有书籍信息的标签。

<table width="100%">标签下的<tr class="item">元素刚好都能满足我们的要求,既有class属性,又包含了书籍的信息。

我们只要取出<tr class="item">元素下<a>元素的title属性的值、<p class="pl">元素、<span class="rating_nums">元素,就能得到书名、出版信息和评分的数据。

在这里插入图片描述
页面分析完毕,接着进入代码实现的步骤。

代码实现——创建项目

从这里开始,我会带你使用Scrapy编写我们的项目爬虫。其中会涉及到很多Scrapy的用法,请你一定要认真地看!

如果你想在自己本地的电脑使用Scrapy,需要提前安装好它。(安装方法:Windows:在终端输入命令:pip install scrapy;mac:在终端输入命令:pip3 install scrapy,按下enter键)

首先,要在本地电脑打开终端(windows:Win+R,输入cmd;mac:command+空格,搜索“终端”),然后跳转到你想要保存项目的目录下。

假设你想跳转到E盘里名为Python文件夹中的Pythoncode子文件夹。你需要再命令行输入e:,就会跳转到e盘,再输入cd Python,就能跳转到Python文件夹。接着输入cd Pythoncode,就能跳转到Python文件夹里的Pythoncode子文件夹。

然后,再输入一行能帮我们创建Scrapy项目的命令:scrapy startproject douban,douban就是Scrapy项目的名字。按下enter键,一个Scrapy项目就创建成功了。

在这里插入图片描述

整个scrapy项目的结构,如下图所示:

在这里插入图片描述
Scrapy项目里每个文件都有特定的功能,比如settings.py 是scrapy里的各种设置。items.py是用来定义数据的,pipelines.py是用来处理数据的,它们对应的就是Scrapy的结构中的Item Pipeline(数据管道)。

现在或许你还看不懂它们,没关系,事情将会一点点变清晰。我们来讲解它们。

代码实现——编辑爬虫

如前所述,spiders是放置爬虫的目录。我们可以在spiders这个文件夹里创建爬虫文件。我们来把这个文件,命名为top250。后面的大部分代码都需要在这个top250.py文件里编写。

在这里插入图片描述
先在top250.py文件里导入我们需要的模块。

import scrapy
import bs4

导入BeautifulSoup用于解析和提取数据,这个应该不需要我多做解释。在第2关、第3关的时候你就已经对它非常熟稔。

导入scrapy是待会我们要用创建类的方式写这个爬虫,我们所创建的类将直接继承scrapy中的scrapy.Spider类。这样,有许多好用属性和方法,就能够直接使用。

接着我们开始编写爬虫的核心代码。

在Scrapy中,每个爬虫的代码结构基本都如下所示:

class DoubanSpider(scrapy.Spider):name = 'douban'allowed_domains = ['book.douban.com']start_urls = ['https://book.douban.com/top250?start=0']def parse(self, response):print(response.text)

第1行代码:定义一个爬虫类DoubanSpider。就像我刚刚讲过的那样,DoubanSpider类继承自scrapy.Spider类。

第2行代码:name是定义爬虫的名字,这个名字是爬虫的唯一标识。name = 'douban’意思是定义爬虫的名字为douban。等会我们启动爬虫的时候,要用到这个名字。

第3行代码:allowed_domains是定义允许爬虫爬取的网址域名(不需要加https://)。如果网址的域名不在这个列表里,就会被过滤掉。

为什么会有这个设置呢?当你在爬取大量数据时,经常是从一个URL开始爬取,然后关联爬取更多的网页。比如,假设我们今天的爬虫目标不是爬书籍信息,而是要爬豆瓣图书top250的书评。我们会先爬取书单,再找到每本书的URL,再进入每本书的详情页面去抓取评论。

allowed_domains就限制了,我们这种关联爬取的URL,一定在book.douban.com这个域名之下,不会跳转到某个奇怪的广告页面。

第4行代码:start_urls是定义起始网址,就是爬虫从哪个网址开始抓取。在此,allowed_domains的设定对start_urls里的网址不会有影响。

第6行代码:parse是Scrapy里默认处理response的一个方法,中文是解析。

你或许会好奇,这里是不是少了一句类似requests.get()这样的代码?的确是,在这里,我们并不需要写这一句。scrapy框架会为我们代劳做这件事,写好你的请求,接下来你就可以直接写对响应如何做处理,我会在后面为你做示例。

了解完爬虫代码的基础结构,我们继续来完善爬取豆瓣Top图书的代码。

在这里插入图片描述
豆瓣Top250图书一共有10页,每一页的网址我们都知道。我们可以选择把10页网址都塞进start_urls的列表里。

但是这样的方式并不美观,而且如果要爬取的是上百个网址,全部塞进start_urls的列表里的话,代码就会非常长。

其实,我们可以利用豆瓣Top250图书的网址规律,用for循环构造出每个网址,再把网址添加进start_urls的列表里。这样代码会美观得多。

在这里插入图片描述
完善后的代码如下:

class DoubanSpider(scrapy.Spider):name = 'douban'allowed_domains = ['book.douban.com']start_urls = []for x in range(3):url = 'https://book.douban.com/top250?start=' + str(x * 25)start_urls.append(url)

我们只先爬取豆瓣Top250前3页的书籍信息。

接下来,只要再借助parse方法处理response,借助BeautifulSoup来取出我们想要的书籍信息的数据,代码即可完成。

我们前面在分析项目过程的时候,已经知道书籍信息都藏在了哪些元素里,现在可以利用find_all和find方法提取出来。比如,书名是元素下元素的title属性的值;出版信息在

元素里;评分在元素里。

按照过去的知识,我们可能会把代码写成这个模样:

import scrapy
import bs4
from ..items import DoubanItemclass DoubanSpider(scrapy.Spider):
#定义一个爬虫类DoubanSpider。name = 'douban'#定义爬虫的名字为douban。allowed_domains = ['book.douban.com']#定义爬虫爬取网址的域名。start_urls = []#定义起始网址。for x in range(3):url = 'https://book.douban.com/top250?start=' + str(x * 25)start_urls.append(url)#把豆瓣Top250图书的前3页网址添加进start_urls。def parse(self, response):#parse是默认处理response的方法。bs = bs4.BeautifulSoup(response.text,'html.parser')#用BeautifulSoup解析response。datas = bs.find_all('tr',class_="item")#用find_all提取<tr class="item">元素,这个元素里含有书籍信息。for data in  datas:#遍历datas。title = data.find_all('a')[1]['title']#提取出书名。publish = data.find('p',class_='pl').text#提取出出版信息。score = data.find('span',class_='rating_nums').text#提取出评分。print([title,publish,score])#打印上述信息。

按照过去,我们会把书名、出版信息、评分,分别赋值,然后统一做处理——或是打印,或是存储。但在scrapy这里,事情却有所不同。

spiders(如top250.py)只干spiders应该做的事。对数据的后续处理,另有人负责。

代码实现——定义数据

在scrapy中,我们会专门定义一个用于记录数据的类。

当我们每一次,要记录数据的时候,比如前面在每一个最小循环里,都要记录“书名”,“出版信息”,“评分”。我们会实例化一个对象,利用这个对象来记录数据。

每一次,当数据完成记录,它会离开spiders,来到Scrapy Engine(引擎),引擎将它送入Item Pipeline(数据管道)处理。

定义这个类的py文件,正是items.py。

我们已经知道,我们要爬取的数据是书名、出版信息和评分,我们来看看如何在items.py里定义这些数据。代码如下:

import scrapy
#导入scrapy
class DoubanItem(scrapy.Item):
#定义一个类DoubanItem,它继承自scrapy.Itemtitle = scrapy.Field()#定义书名的数据属性publish = scrapy.Field()#定义出版信息的数据属性score = scrapy.Field()#定义评分的数据属性

第1行代码,我们导入了scrapy。目的是,我们等会所创建的类将直接继承scrapy中的scrapy.Item类。这样,有许多好用属性和方法,就能够直接使用。比如到后面,引擎能将item类的对象发给Item Pipeline(数据管道)处理。

第3行代码:我们定义了一个DoubanItem类。它继承自scrapy.Item类。

第5、7、9行代码:我们定义了书名、出版信息和评分三种数据。scrapy.Field()这行代码实现的是,让数据能以类似字典的形式记录。你可能不太明白这句话的含义,没关系。我带你来体验一下,你就能感受到是怎样一回事:

import scrapy
#导入scrapy
class DoubanItem(scrapy.Item):
#定义一个类DoubanItem,它继承自scrapy.Itemtitle = scrapy.Field()#定义书名的数据属性publish = scrapy.Field()#定义出版信息的数据属性score = scrapy.Field()#定义评分的数据属性book = DoubanItem()
# 实例化一个DoubanItem对象
book['title'] = '海边的卡夫卡'
book['publish'] = '[日] 村上春树 / 林少华 / 上海译文出版社 / 2003'
book['score'] = '8.1'
print(book)
print(type(book))

运行结果:

{'publish': '[日] 村上春树 / 林少华 / 上海译文出版社 / 2003','score': '8.1','title': '海边的卡夫卡'}
<class '__main__.DoubanItem'>

你会看到打印出来的结果的确和字典非常相像,但它却并不是dict,它的数据类型是我们定义的DoubanItem,属于“自定义的Python字典”。我们可以利用类似上述代码的样式,去重新写top250.py。如下所示:

import scrapy
import bs4
from ..items import DoubanItem
# 需要引用DoubanItem,它在items里面。因为是items在top250.py的上一级目录,所以要用..items,这是一个固定用法。class DoubanSpider(scrapy.Spider):
#定义一个爬虫类DoubanSpider。name = 'douban'#定义爬虫的名字为douban。allowed_domains = ['book.douban.com']#定义爬虫爬取网址的域名。start_urls = []#定义起始网址。for x in range(3):url = 'https://book.douban.com/top250?start=' + str(x * 25)start_urls.append(url)#把豆瓣Top250图书的前3页网址添加进start_urls。def parse(self, response):#parse是默认处理response的方法。bs = bs4.BeautifulSoup(response.text,'html.parser')#用BeautifulSoup解析response。datas = bs.find_all('tr',class_="item")#用find_all提取<tr class="item">元素,这个元素里含有书籍信息。for data in  datas:#遍历data。item = DoubanItem()#实例化DoubanItem这个类。item['title'] = data.find_all('a')[1]['title']#提取出书名,并把这个数据放回DoubanItem类的title属性里。item['publish'] = data.find('p',class_='pl').text#提取出出版信息,并把这个数据放回DoubanItem类的publish里。item['score'] = data.find('span',class_='rating_nums').text#提取出评分,并把这个数据放回DoubanItem类的score属性里。print(item['title'])#打印书名。yield item#yield item是把获得的item传递给引擎。

在3行,我们需要引用DoubanItem,它在items里面。因为是items在top250.py的上一级目录,所以要用…items,这是一个固定用法。

当我们每一次,要记录数据的时候,比如前面在每一个最小循环里,都要记录“书名”,“出版信息”,“评分”。我们会实例化一个item对象,利用这个对象来记录数据。

每一次,当数据完成记录,它会离开spiders,来到Scrapy Engine(引擎),引擎将它送入Item Pipeline(数据管道)处理。这里,要用到yield语句。

yield语句你可能还不太了解,这里你可以简单理解为:它有点类似return,不过它和return不同的点在于,它不会结束函数,且能多次返回信息。

在这里插入图片描述
如果用可视化的方式来呈现程序运行的过程,就如同上图所示:爬虫(Spiders)会把豆瓣的10个网址封装成requests对象,引擎会从爬虫(Spiders)里提取出requests对象,再交给调度器(Scheduler),让调度器把这些requests对象排序处理。

然后引擎再把经过调度器处理的requests对象发给下载器(Downloader),下载器会立马按照引擎的命令爬取,并把response返回给引擎。

紧接着引擎就会把response发回给爬虫(Spiders),这时爬虫会启动默认的处理response的parse方法,解析和提取出书籍信息的数据,使用item做记录,返回给引擎。引擎将它送入Item Pipeline(数据管道)处理。

代码实操——设置

到这里,我们就用代码编写好了一个爬虫。不过,实际运行的话,可能还是会报错。

原因在于Scrapy里的默认设置没被修改。比如我们需要修改请求头。点击settings.py文件,你能在里面找到如下的默认设置代码:

# Crawl responsibly by identifying yourself (and your website) on the user-agent
#USER_AGENT = 'douban (+http://www.yourdomain.com)'# Obey robots.txt rules
ROBOTSTXT_OBEY = True

请你把USER _AGENT的注释取消(删除#),然后替换掉user-agent的内容,就是修改了请求头。

又因为Scrapy是遵守robots协议的,如果是robots协议禁止爬取的内容,Scrapy也会默认不去爬取,所以我们还得修改Scrapy中的默认设置。

把ROBOTSTXT_OBEY=True改成ROBOTSTXT_OBEY=False,就是把遵守robots协议换成无需遵从robots协议,这样Scrapy就能不受限制地运行。

修改后的代码应该如下所示:

# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36'# Obey robots.txt rules
ROBOTSTXT_OBEY = False

现在,我们已经编写好了spider,也修改好了setting。万事俱备,只欠东风——运行Scrapy。

代码实操——运行

想要运行Scrapy有两种方法,一种是在本地电脑的终端跳转到scrapy项目的文件夹(跳转方法:cd+文件夹的路径名),然后输入命令行:scrapy crawl douban(douban 就是我们爬虫的名字)。

在这里插入图片描述
另一种运行方式需要我们在最外层的大文件夹里新建一个main.py文件(与scrapy.cfg同级)。

在这里插入图片描述

我们只需要在这个main.py文件里,输入以下代码,点击运行,Scrapy的程序就会启动。

from scrapy import cmdline
#导入cmdline模块,可以实现控制终端命令行。
cmdline.execute(['scrapy','crawl','douban'])
#用execute()方法,输入运行scrapy的命令。

第1行代码:在Scrapy中有一个可以控制终端命令的模块cmdline。导入了这个模块,我们就能操控终端。

第3行代码:在cmdline模块中,有一个execute方法能执行终端的命令行,不过这个方法需要传入列表的参数。我们想输入运行Scrapy的代码scrapy crawl douban,就需要写成[‘scrapy’,‘crawl’,‘douban’]这样。

至此,Scrapy的用法我们学完啦。

值得一提的是,在本关卡中为了教学方便理解,先写了爬虫,再定义数据。但是,在实际项目实战中,常常顺序却是相反的——先定义数据,再写爬虫。所以,流程图应如下:

在这里插入图片描述
细心的你可能会发现,这一关的内容没有涉及到存储数据的步骤。

是的,存储数据需要修改pipelines.py文件。这一关的内容已经很充实,所以这个知识点我们留到下一关再讲。

复习

最后,是这一关的重点知识的复习。

Scrapy的结构——

在这里插入图片描述
Scrapy的工作原理——

在这里插入图片描述
Scrapy的用法——

在这里插入图片描述
下一关,我们准备用Scrapy来实操一个大项目——爬取人气企业的招聘信息。

下关见啦~

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

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

相关文章

【JAVA】多态

作者主页&#xff1a;paper jie_的博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文录入于《JAVASE语法系列》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和…

开源django+mysql+vue3前后端分离商城baykeShop使用指南

baykeShop开源商城系统 项目简介 baykeShop&#xff08;拜客商城系统&#xff09;是一款全开源Python栈商城系统&#xff0c;管理后台完全前后端分离重写以适配项目&#xff0c;前后端100%开源&#xff0c;后台前端采用开源SCUI开源库对接开发&#xff0c;美观、易用、符合当…

【广州华锐互动】数字孪生智慧楼宇3D可视化系统:掌握实时运行状态,优化运营管理

在过去的几年中&#xff0c;科技的发展极大地改变了我们的生活和工作方式。其中&#xff0c;三维数据可视化技术的出现&#xff0c;为我们提供了全新的理解和观察世界的方式。特别是在建筑行业&#xff0c;数字孪生智慧楼宇3D可视化系统的出现&#xff0c;让我们有机会重新定义…

面试题 ⑤

1、TCP与UDP的区别 UDPTCP是否连接无连接&#xff0c;即刻传输面向连接&#xff0c;三次握手是否可靠不可靠传输&#xff0c;网络波动拥堵也不会减缓传输可靠传输&#xff0c;使用流量控制和拥塞控制连接对象个数支持一对一&#xff0c;一对多&#xff0c;多对一和多对多交互通…

排序算法问题

给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 示例 1&#xff1a; 输入&#xff1a;nums [5,2,3,1] 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;nums [5,1,1,2,0,0] 输出&#xff1a;[0,0,1,1,2,5] 代码如下&#xff1a; 1.插入排序(简…

【VM】保姆级VM算法平台二次开发之-环境配置

VM算法平台二次开发 1.下载Visual Studio 20222.项目的创建 C# 应用3.设置属性&#xff0c;去掉属选型32位4. 进行引用的导入工作5. 重新加载&#xff0c;查看引用6. 工具箱添加Dll的依赖。&#xff08;只需要加载一次就行&#xff09; 1.下载Visual Studio 2022 可以直接在官…

python中super()用法

super关键字的用法 一、概述二、作用三、语法四、使用示例1.通过super() 来调用父类的__init__ 构造方法&#xff1a;2.通过supper() 来调用与子类同名的父类方法2.1 单继承2.2 多继承 一、概述 super() 是python 中调用父类&#xff08;超类&#xff09;的一种方法&#xff0…

R语言+Meta分析;论文新方向

Meta分析是针对某一科研问题&#xff0c;根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法&#xff0c;对来源不同的研究成果进行收集、合并及定量统计分析的方法&#xff0c;最早出现于“循证医学”&#xff0c;现已广泛应用于农林生态&#xff0c;资源环境等方面。…

如何使用ArcGIS Earth制作地图动画视频

通常情况下&#xff0c;我们所看到的地图都是静态展示&#xff0c;对于信息的传递&#xff0c;视频比图片肯定会更加丰富&#xff0c;所以制作地图动画视频更加有利于信息的传递&#xff0c;这里我们讲解一下ArcGIS Earth 2.0如何制作地图动画视频&#xff0c;希望能对你有所帮…

3.2.0 终极预告!云原生支持新增 Spark on k8S 支持

视频贡献者 | 王维饶 视频制作者 | 聂同学 编辑整理 | Debra Chen Apache DolphinScheduler 3.2.0 版本将发布&#xff0c;为了让大家提前了解到此版本更新的主要内容&#xff0c;我们已经制作了几期视频和内容做了大致介绍&#xff0c;包括《重磅预告&#xff01;Apache Dol…

AI:04-基于机器学习的蘑菇分类

蘑菇是一类广泛分布的真菌,其中许多种类具有重要的食用和药用价值,但也存在着一些有毒蘑菇。因此,准确地区分可食用和有毒的蘑菇对于保障人们的食品安全和健康至关重要。本研究旨在基于机器学习技术开发一种蘑菇分类系统,以实现对蘑菇的自动分类和识别。通过构建合适的数据…

springboot基础(79):通过pdf模板生成文件

文章目录 前言通过pdf模板生成文件一 . 制作模板二、编辑代码实现模板生成pdf文件三、pdf在线预览和文件下载 扩展问题遇到的问题1. 更换字体为宋体常规2. 下载时中文文件名乱码问题 前言 通过pdf模板生成文件。 支持文本&#xff0c;图片&#xff0c;勾选框。 本章代码已分享…

17.Oauth2-微服务认证

1.Oauth2 OAuth 2.0授权框架支持第三方支持访问有限的HTTP服务&#xff0c;通过在资源所有者和HTTP服务之间进行一个批准交互来代表资源者去访问这些资源&#xff0c;或者通过允许第三方应用程序以自己的名义获取访问权限。 为了方便理解&#xff0c;可以想象OAuth2.0就是在用…

实现 Entity实例生命周期和vue组件生命周期融合

场景解决方案实现方案index.vue方案解决效果 场景 ceisum中Entity实例的生成和销毁&#xff0c;大部分逻辑和vue代码分离&#xff0c;导致不好阅读和维护 解决方案 ceisum 中实例 Entity 的生命周期&#xff0c;和vue的生命周期’相似’&#xff0c;把两个生命周期结合(把en…

Jmete+Grafana+Prometheus+Influxdb+Nginx+Docker架构搭建压测体系/监控体系/实时压测数据展示平台+遇到问题总结

背景 需要大批量压测时&#xff0c;单机发出的压力能力有限&#xff0c;需要多台jmeter来同时进行压测&#xff1b;发压机资源不够&#xff0c;被压测系统没到瓶颈之前&#xff0c;发压机难免先发生资源不足的情形&#xff1b;反复压测时候也需要在不同机器中启动压测脚本&…

比较opencv,pillow,matplotlib,skimage读取图像的速度比

上面这些库都被广泛用于图像处理和计算机视觉任务&#xff1b; 不同的图像读取库&#xff08;OpenCV&#xff0c;Pillow&#xff0c;matplotlib和skimage&#xff09;的读取速度&#xff0c;是怎么样的一个情况&#xff1f; 下面分别从读取速度&#xff0c;以及转换到RGB通道…

《虚拟仿真实验教学平台》三项团体标准启动会在 ALVA 举办

8 月 11 日&#xff0c;《虚拟仿真实验教学平台》三项团体标准启动会&#xff08;下以“启动会”简称&#xff09;以线下线上相结合的会议形式在 ALVA Systems 北京总部举办。 启动会上&#xff0c;ALVA 与专家组、编写组成员和企业代表围绕《虚拟仿真实验教学平台建设指南》、…

不同写法的性能差异

“ 达到相同目的,可以有多种写法,每种写法有性能、可读性方面的区别,本文旨在探讨不同写法之间的性能差异 len(str) vs str "" 本部分参考自: [问个 Go 问题&#xff0c;字符串 len 0 和 字符串 "" &#xff0c;有啥区别&#xff1f;](https://segmentf…

基础算法-递推算法-学习

现象&#xff1a; 基础算法-递推算法-学习 方法&#xff1a; 这就是一种递推的算法思想。递推思想的核心就是从已知条件出发&#xff0c;逐步推算出问题的解 最常见案例&#xff1a; 一&#xff1a;正向递推案例&#xff1a; 弹力球回弹问题&#xff1a; * 弹力球从100米高…

OpenLayers7官方文档翻译,OpenLayers7中文文档,OpenLayers快速入门

快速入门 这个入门文档向您展示如何放一张地图在web网页上。 开发设置使用 NodeJS&#xff08;至少需要Nodejs 14 或更高版本&#xff09;&#xff0c;并要求安装 git。 设置新项目 开始使用OpenLayers构建项目的最简单方法是运行&#xff1a;npm create ol-app npm create…