1. 创建一个scrapy项目:scrapy startproject mySpider

  2. 生成一个爬虫:scrapy genspider douban movie.douban.com

  3. 提取数据:完善spider,使用xpath等方法

  4. 保存数据:pipeline中保存数据

2 创建scrapy项目

下面以抓取豆瓣top250来学习scrapy的入门使用:豆瓣电影 Top 250

安装scrapy命令:sudo apt-get install scrapyscrapy==2.5.0 或者:pip install scrapy==2.5.0

1.创建项目面板
scrapy 2.5.0 - no active project
​
usage:scrapy <command>[options] [args]
​
Available commands :bench      Run quick benchmark test #测试电脑性能fetch      Fetch a URL using the scrapy down1oader#将源代码下载下来并显示出来genspider      Generate new spider using pre-defined temp1ates#创建一个新的spider文件runspider      Run a self-contained spider (without creating a project)# 这个和通过craw1启动爬虫不同,scrapy runspider爬虫文件名称settings      Get settings values#获取当前的配置信息she11      Interactive scraping console#进入scrapy 的交互模式startproject      create new project#创建爬虫项目version      Print scrapy version#显示scrapy框架的版本view      open URL in browser,as seen by scrapy#将网页document内容下载下来,并且在浏览器显示出来

创建scrapy项目的命令:scrapy startproject +<项目名字>

示例:scrapy startproject myspider

生成的目录和文件结果如下:

3 创建爬虫

命令:在项目路径下执行:scrapy genspider +<爬虫名字> + <允许爬取的域名>

示例:

cd myspider
scrapy genspider douban movie.douban.com

生成的目录和文件结果如下:

4 完善spider

完善spider即通过方法进行数据的提取等操作

在\myspider\myspider\douban.py中修改内容如下:

import scrapy
from scrapy.http import HtmlResponse
# 自定义spider类,继承scrapy.spider
class DoubanSpider(scrapy.Spider):# 爬虫名字name = 'douban'# 允许爬取的范围,防止爬虫爬到别的网站allowed_domains = ['douban.com']# 开始爬取的url地址start_urls = ['https://movie.douban.com/top250']
​# 数据提取的方法,接受下载中间件传过来的responsedef parse(self, response:HtmlResponse, **kwargs):# scrapy的response对象可以直接进行xpathol_list = response.xpath('//ol[@class="grid_view"]/li')print(ol_list)for ol in ol_list:# 创建一个数据字典item = {}# 利用scrapy封装好的xpath选择器定位元素,并通过extract()或extract_first()来获取结果item['title'] = ol.xpath('.//div[@class="hd"]/a/span[1]/text()').extract_first()item['rating'] = ol.xpath('.//div[@class="bd"]/div/span[2]/text()').extract_first()item['quote'] = ol.xpath('.//div[@class="bd"]//p[@class="quote"]/span/text()').extract_first()print(item)

注意:

  1. response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法

  2. extract() 返回一个包含有字符串的列表

  3. extract_first() 返回列表中的第一个字符串,列表为空没有返回None

  4. spider中的parse方法必须有

  5. 需要抓取的url地址必须属于allowed_domains,但是start_urls中的url地址没有这个限制

  6. 启动爬虫的时候注意启动的位置,是在项目路径下启动

4.1 response对象属性
  1. url HTTP相应的 URL地址,str类型的

  2. status HTTP响应状态码,int类型的(在pycharm的控制台中你可以看到,例如200,404)

  3. body HTTP响应正文,bytes类型

  4. text 文本形式的HTTP响应正文,str类型,由response.body使用response.encoding解码得到

  5. encoding HTTP响应正文的编码

  6. request 产生该HTTP响应的Requset对象

  7. selector (这个比较重要了)选择器对象用来提取response中的数据

  8. xpath(query) 即xml路径语言,用来确定xml文档中某部分位置的语言(html属性xml)

  9. css(query) 也是一种选择器,用来提取页面内中的数据,但是不如xpath强大。

  10. urljoin(url) 用来构造绝对url

5 利用管道pipeline来处理(保存)数据

5.1 对douban爬虫进行修改完善

在爬虫文件douban.py中parse()函数中最后添加

yield item

注意:yield能够传递的对象只能是:BaseItem,Request,dict,None

5.2 修改pipelines.py文件
class MyspiderPipeline:# 爬虫文件中提取数据的方法每yield一次item,就会运行一次# 该方法为固定名称函数def process_item(self, item, spider):print(item)
5.3 在settings.py设置开启pipeline
ITEM_PIPELINES = {'myspider.pipelines.MyspiderPipeline': 300,
}
​
# 协议证书配置
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
​
# 带上请求头
# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36'
}

6 运行scrapy

6.1命令运行

命令:在项目目录下执行scrapy crawl +<爬虫名字>

示例:scrapy crawl douban --nolog

6.2 debug运行
# scrapy封装的命令执行
from scrapy import cmdline
​
if __name__ == '__main__':# 解析的是一个列表对象# 获取的json文件会乱码 需要修改配置 FEED_EXPORT_ENCODING = 'utf-8'cmdline.execute('scrapy crawl douban -o douban.json -s FEED_EXPORT_ENCODING="utf-8"'.split())

注意:

  • 安装2.5版本之后运行代码可能会遇到以下错误

AttributeError: module 'OpenSSL.SSL' has no attribute 'SSLv3_METHOD'
ImportError: cannot import name 'HTTPClientFactory' from 'twisted.web.client' (unknown location)
  • 降低OpenSSL和cryptography以及Twisted的版本

pip install pyOpenSSL==22.0.0
pip install cryptography==38.0.4
pip install Twisted==20.3.0
# 或者
pip install cryptography==3.4.8
pip install pyOpenSSL==21.0.0
  • 异步报错

TypeError: ProactorEventLoop is not supported, got: <ProactorEventLoop running=False closed=False debug=False>
  • 这个错误通常表示正在尝试在不支持 ProactorEventLoop 的操作系统上运行Scrapy。Scrapy目前不支持Windows上的ProactorEventLoop,因此您需要将其更改为SelectorEventLoop

  • 可以通过在Scrapy项目的settings.py文件中添加以下代码来更改默认的事件循环

import asyncio
if hasattr(asyncio, "WindowsSelectorEventLoopPolicy"):asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
  • 2.5的版本适配的是3.7的py版本,需要找到你解释器对应的版本信息

  • 可以运行尝试

7.输出的数据日志信息

7.1 日志等级
  • CRITICAL:严重错误

  • ERROR:一般错误

  • WARNING:警告

  • INFO: 一般信息

  • DEBUG:调试信息

注意: 默认的日志等级是DEBUG

7.2日志输出信息
Versions:使用的工具版本信息
Overridden settings: 重写的配置
Telnet Password:Telnet 平台密码(Scrapy附带一个内置的telnet控制台,用于检查和控制Scrapy运行过程)
Enabled extensions :开启的拓展功能
Enabled downloader middlewares:开启的下载器中间件
Enabled spider middlewares:开启的爬虫中间件
Enabled item pipelines:开启的管道
Dumping Scrapy stats:所以的信息汇总
7.3 日志等级设置
  • 修改settings.py文件

LOG_LEVEL = 'WARNING' # 设置日志显示的等级为WARNING
LOG_FILE = './log.txt' # 将日志信息全部记录到log.txt文件中

三、scrapy发送翻页请求

1. 翻页请求的思路

回顾requests模块是如何实现翻页请求的:

  1. 找到下一页的URL地址

  2. 调用requests.get(url)

scrapy实现翻页的思路:

  1. 找到下一页的url地址

  2. 构造url地址的请求,传递给引擎

2 scrapy实现翻页请求

2.1 实现方法
  1. 确定url地址

  2. 构造请求,scrapy.Request(url,callback)

    • callback:指定解析函数名称,表示该请求返回的响应使用哪一个函数进行解析

  3. 把请求交给引擎:yield scrapy.Request(url,callback)

2.2 豆瓣爬虫

通过爬取豆瓣top250页面的电影信息,学习如何实现翻页请求

地址:豆瓣电影 Top 250

思路分析:
  1. 获取首页的数据

  2. 寻找下一页的地址,进行翻页,获取数据

注意:
  1. 可以在settings中设置ROBOTS协议

    # False表示忽略网站的robots.txt协议,默认为True
    ROBOTSTXT_OBEY = False
    ​
  2. 可以在settings中设置User-Agent:

    # scrapy发送的每一个请求的默认UA都是设置的这个User-Agent
    USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'
    ​
2.3 代码实现

在爬虫文件的parse方法中:

# 数据提取的方法,接受下载中间件传过来的responsedef parse(self, response):# print(response.urljoin('asfd'))# scrapy的response对象可以直接进行xpathol_list = response.xpath('//ol[@class="grid_view"]/li')# 提取下一页的href并拼接url# print(ol_list)for ol in ol_list:# 创建一个数据字典# item = MyspiderItem()item = {}# 利用scrapy封装好的xpath选择器定位元素,并通过extract()或extract_first()来获取结果item['title'] = ol.xpath('.//div[@class="hd"]/a/span[1]/text()').extract_first()item['rating'] = ol.xpath('.//div[@class="bd"]/div/span[2]/text()').extract_first()item['quote'] = ol.xpath('.//div[@class="bd"]//p[@class="quote"]/span/text()').extract_first()print(item)yield itemif response.xpath("//a[text()='后页>']/@href").extract_first() != None:next_url = response.urljoin(response.xpath("//a[text()='后页>']/@href").extract_first())print(next_url)yield scrapy.Request(url=next_url, callback=self.parse)

2.4 scrapy.Request的更多参数
scrapy.Request(url[,callback,method="GET",headers,body,cookies,\
meta,dont_filter=False])
参数解释
  1. 中括号中的参数为可选参数

  2. callback:表示当前的url的响应交给哪个函数去处理

  3. meta:实现数据在不同的解析函数中传递,meta默认带有部分数据,比如下载延迟,请求深度等

  4. dont_filter:默认为False,会过滤请求的url地址,即请求过的url地址不会继续被请求,对需要重复请求的url地址可以把它设置为Ture,比如贴吧的翻页请求,页面的数据总是在变化;start_urls中的地址会被反复请求,否则程序不会启动

  5. method:指定POST或GET请求

  6. headers:接收一个字典,其中不包括cookies

  7. cookies:接收一个字典,专门放置cookies

  8. body:接收一个字典,为POST的数据

2.5 重写start_requests方法

上述方法可以帮助我们实现翻页的问题,但是这种翻页并不是框架的最优解,我们可以重写Spider的start_requests方法,自己生成对应的请求网址给到引擎进行调度

    def start_requests(self):for i in range(0, 10):url = 'https://movie.douban.com/top250?start={}&filter='.format(i * 25)yield scrapy.Request(url)

3 meta参数的使用

meta的形式:字典
meta的作用:meta可以实现数据在不同的解析函数中的传递

在爬虫文件的parse方法中,提取详情页增加之前callback指定的parse_detail函数:

def parse(self,response):...yield scrapy.Request(detail_url, callback=self.parse_detail,meta={"item":item})
...
​
def parse_detail(self,response):#获取之前传入的itemitem = resposne.meta["item"]
​
特别注意
  1. meta参数是一个字典

  2. meta字典中有一个固定的键proxy,表示代理ip,关于代理ip的使用我们将在scrapy的下载中间件的学习中进行介绍

  3. meta的download_timeout设置请求超时

4. item的使用

4.1 Item能够做什么
  1. 定义item即提前规划好哪些字段需要抓取,scrapy.Field()仅仅是提前占坑,通过item.py能够让别人清楚自己的爬虫是在抓取什么,同时定义好哪些字段是需要抓取的,没有定义的字段不能使用,防止手误

  2. 在python大多数框架中,大多数框架都会自定义自己的数据类型(在python自带的数据结构基础上进行封装),目的是增加功能,增加自定义异常

4.2 定义Item

在items.py文件中定义要提取的字段:

class MyspiderItem(scrapy.Item):title = scrapy.Field()  # 标题rating = scrapy.Field()  # 评估quote = scrapy.Field()  # 概述
4.3 使用Item

Item使用之前需要先导入并且实例化,之后的使用方法和使用字典相同

修改爬虫文件douban.py:

from myspider.items import MyspiderItem  # 导入Item,注意路径
...def parse(self, response):# print(response.meta['data'])ol_list = response.xpath('//ol[@class="grid_view"]/li')
​for ol in ol_list:item = MyspiderItem()item['title'] = ol.xpath('.//div[@class="hd"]/a/span[1]/text()').extract_first()item['rating'] = ol.xpath('.//div[@class="bd"]/div/span[2]/text()').extract_first()item['quote'] = ol.xpath('.//div[@class="bd"]//p[@class="quote"]/span/text()').extract_first()# item['yeshu'] = response.meta['data']# print(item)yield item
注意:
  1. from myspider.items import MyspiderItem这一行代码中 注意item的正确导入路径,忽略pycharm标记的错误

  2. python中的导入路径要诀:从哪里开始运行,就从哪里开始导入

四、scrapy的管道使用

1. 了解scrapyShell

scrapy shell是scrapy提供的一个终端工具,能够通过它查看scrapy中对象的属性和方法,以及测试xpath

使用方法:

scrapy shell https://movie.douban.com/top250

在终端输入上述命令后,能够进入python的交互式终端,此时可以使用:

  • response.xpath():直接测试xpath规则是否正确

  • response.url:当前响应的url地址

  • response.request.url:当前响应对应的请求的url地址

  • response.headers:响应头

  • response.body:响应体,也就是html代码,默认是byte类型

  • response.requests.headers:当前响应的请求头

3 settings.py中的设置信息

3.1 为什么项目中需要配置文件

在配置文件中存放一些公共变量,在后续的项目中方便修改,如:本地测试数据库和部署服务器的数据库不一致

3.2 配置文件中的变量使用方法
  1. 变量名一般全部大写

  2. 导入即可使用

3.3 settings.py中的重点字段和含义
  • USER_AGENT 设置ua

  • ROBOTSTXT_OBEY 是否遵守robots协议,默认是遵守

  • CONCURRENT_REQUESTS 设置并发请求的数量,默认是16个

  • DOWNLOAD_DELAY 下载延迟,默认无延迟

  • COOKIES_ENABLED 是否开启cookie,即每次请求带上前一次的cookie,默认是开启的

  • DEFAULT_REQUEST_HEADERS 设置默认请求头

  • SPIDER_MIDDLEWARES 爬虫中间件,设置过程和管道相同

  • DOWNLOADER_MIDDLEWARES 下载中间件

  • LOG_LEVEL 控制终端输出信息的log级别,终端默认显示的是debug级别的log信息

    • LOG_LEVEL = "WARNING"

  • LOG_FILE 设置log日志文件的保存路径,如果设置该参数,终端将不再显示信息

    • LOG_FILE = "./test.log"

  • 其他设置参考:Scrapy爬虫入门教程十三 Settings(设置) - 简书

4 pipeline管道的深入使用

4.1 pipeline中常用的方法:
  1. process_item(self,item,spider):实现对item数据的处理

  2. open_spider(self, spider): 在爬虫开启的时候仅执行一次

  3. close_spider(self, spider): 在爬虫关闭的时候仅执行一次

4.2 管道文件的修改

在pipelines.py代码中完善

import pymysql
import pymongo
​
​
class MyspiderMySQLPipeline:def open_spider(self, spider):# 判断是哪个爬虫  名字不同可能执行的爬虫项目也不同if spider.name == 'douban':self.db = pymysql.connect(host="localhost", user="root", password="root", db="spiders9")self.cursor = self.db.cursor()# 创建变语法sql = '''CREATE TABLE IF NOT EXISTS douban(id int primary key auto_increment not null,quote VARCHAR(255) NOT NULL, rating VARCHAR(255) NOT NULL, title VARCHAR(255) NOT NULL)'''try:self.cursor.execute(sql)print("CREATE TABLE SUCCESS.")except Exception as ex:print(f"CREATE TABLE FAILED,CASE:{ex}")
​def process_item(self, item, spider):# SQL 插入语句sql = 'INSERT INTO douban(id, quote, rating, title) values(%s, %s, %s, %s)'# 执行 SQL 语句try:self.cursor.execute(sql, (0, item['quote'], item['rating'], item['title']))# 提交到数据库执行self.db.commit()print('mysql数据插入成功...')except Exception as e:print(f'数据插入失败: {e}')# 如果发生错误就回滚self.db.rollback()# 不return的情况下,另一个权重较低的pipeline将不会获得item,否则后一个pipeline取到的数据为None值return item 
​def close_spider(self, spider):  # 在爬虫关闭的时候仅执行一次# 关闭文件if spider.name == 'douban':self.db.close()
​
​
class MyspiderMongoDBPipeline:def open_spider(self, spider):  # 在爬虫开启的时候仅执行一次if spider.name == 'douban':con = pymongo.MongoClient(host='127.0.0.1', port=27017)  # 实例化mongoclientself.collection = con.spiders9.douban  # 创建数据库名为spiders9,集合名为douban的集合操作对象
​def process_item(self, item, spider):if spider.name == 'douban':print('mongo保存成功')self.collection.insert_one(dict(item))  # 此时item对象需要先转换为字典,再插入# 不return的情况下,另一个权重较低的pipeline将不会获得itemreturn item
4.3 开启管道

在settings.py设置开启pipeline

ITEM_PIPELINES = {'myspider.pipelines.MyspiderMySQLPipeline': 300,'myspider.pipelines.MyspiderMongoDBPipeline': 400,
}

思考:pipeline在settings中能够开启多个,为什么需要开启多个?

  1. 不同的pipeline可以处理不同爬虫的数据,通过spider.name属性来区分

  2. 不同的pipeline能够对一个或多个爬虫进行不同的数据处理的操作,比如一个进行数据清洗,一个进行数据的保存

  3. 同一个管道类也可以处理不同爬虫的数据,通过spider.name属性来区分

4.4 pipeline使用注意点
  1. 使用之前需要在settings中开启

  2. pipeline在setting中键表示位置(即pipeline在项目中的位置可以自定义),值表示距离引擎的远近,越近数据会越先经过

  3. 有多个pipeline的时候,process_item的方法必须return item,否则后一个pipeline取到的数据为None值

  4. pipeline中process_item的方法必须有,否则item没有办法接受和处理

  5. process_item方法接受item和spider,其中spider表示当前传递item过来的spider

  6. open_spider(spider) :能够在爬虫开启的时候执行一次

  7. close_spider(spider) :能够在爬虫关闭的时候执行一次

  8. 上述俩个方法经常用于爬虫和数据库的交互,在爬虫开启的时候建立和数据库的连接,在爬虫关闭的时候断开和数据库的连接

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

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

相关文章

【Elasticsearch】TF-IDF 和 BM25相似性算法

在 Elasticsearch 中&#xff0c;TF-IDF 和 BM25 是两种常用的文本相似性评分算法&#xff0c;但它们的实现和应用场景有所不同。以下是对这两种算法的对比以及在 Elasticsearch 中的使用情况&#xff1a; TF-IDF - 定义与原理&#xff1a;TF-IDF 是一种经典的信息检索算法&am…

【QT】控件二(输入类控件、多元素控件、容器类控件与布局管理器)

文章目录 1.输入类控件1.1 LineEdit1.2 Text Edit1.3 Combo Box1.4 SpinBox1.5 Date Edit & Time Edit1.6 Dial1.7 Slider 2. 多元素控件2.1 List Widget2.2 Table Widget2.3 Tree Widget 3. 容器类控件3.1 Group Box3.2 Tab Widget 4. 布局管理器4.1 垂直布局4.2 水平布局…

【Docker基础】Docker镜像管理:docker pull详解

目录 1 Docker镜像基础概念 1.1 什么是Docker镜像&#xff1f; 1.2 镜像与容器的关系 1.3 镜像仓库(Registry) 2 docker pull命令详解 2.1 基本语法 2.2 参数解释 2.3 拉取镜像的基本流程 2.4 镜像分层结构解析 3 docker pull实战指南 3.1 基本使用示例 3.2 指定镜…

PixPin:一个强大且免费的截图贴图工具

PixPin 是一款国产免费的截图工具&#xff0c;支持屏幕截图、屏幕录制&#xff08;GIF&#xff09;、文字识别&#xff08;OCR&#xff09;以及贴图等功能。 高效截图 PixPin 支持自由选择或自动检测窗口&#xff0c;自定义截图区域&#xff0c;像素级精确捕捉&#xff0c;延时…

【测试报告】论坛系统

一、项目背景 1.1 测试目标及测试任务 测试目标旨在保障功能无漏洞、流程顺畅&#xff0c;实现多端显示交互一致&#xff0c;达成高并发场景下响应时间&#xff1c;2 秒等性能指标&#xff0c;抵御 SQL 注入等安全攻击&#xff0c;提升 UI 易用性与提示友好度&#xff1b; 背…

30天pytorch从入门到熟练(day1)

一、总体工作思路 本项目采用“从零构建”的策略&#xff0c;系统性地开展了深度学习模型的开发与优化工作。其目标在于通过全流程自研方式&#xff0c;深入理解模型构建、训练优化、推理部署的关键技术环节。整体路径分为以下核心阶段&#xff1a; 模型初步构建&#xff1a;以…

Subway Surfers Blast × 亚矩阵云手机:手游矩阵运营的终极变现方案

引爆全球&#xff1a;Subway Surfers Blast的流量红利​​ 随着Sybo Games最新力作《Subway Surfers Blast》全球上线&#xff0c;这款休闲消除游戏迅速席卷各大应用商店榜单。对于手游推广者而言&#xff0c;如何高效获取这波流量红利&#xff1f;​​亚矩阵云手机专业手游推…

mysql join的原理及过程

连接过程 每获得一条驱动表记录&#xff0c;就立即到被驱动表寻找匹配的记录。 对于两表连接来说&#xff0c;驱动表只会被访问一遍&#xff0c;但被驱动表却要被访问好多遍;具体访问几遍取决于对驱动表执行单表查询后的结果集中有多少条记录。 ​ 对于内连接来说&#xff0…

Hologres的EXPLAIN和EXPLAIN ANALYZE简介

文章目录 一、执行计划1、概念简介2、使用方式①、EXPLAIN②、EXPLAIN ANALYZE 二、算子解读1、SCAN2、Index Scan和 Index Seek3、Filter4、Decode5、Redistribution6、Join7、Broadcast8、Shard prune和Shards selected9、ExecuteExternalSQL10、Aggregate11、Sort12、Limit1…

49-Oracle init.ora-PFILE-SPFILE-启动参数转换实操

一早出现EMCC挂了&#xff0c;之后发现EMCC依赖的instance 挂了&#xff0c;重启startup后发现spfile无法启动。还是和小伙伴把基础问题搞清。spfile是动态文件、动态文件、动态文件&#xff0c;linux下vi看起来部分乱码部分是可编辑的&#xff0c;vi即使可以编辑也需要转换成p…

spring碎片

包的扫描过程 判断当前是否是文件夹获取文件夹里面的所有内容判断文件夹是否为空,为空的话直接返回如果文件夹不为空,则遍历文件夹里面的所有内容 遍历得到每个file对象,继续进行判断,如果还是文件,则进一步进行递归遍历得到的file对象不是文件夹,是文件得到包路径类名称-字符…

如何形成项目经验在多个项目间的高效复用?

要实现项目经验的跨项目高效复用&#xff0c;核心在于建立系统化总结机制、标准化知识表达、平台化共享工具。其中&#xff0c;标准化知识表达尤为关键&#xff0c;它通过统一模板和分类体系&#xff0c;确保不同项目的经验可以被快速理解、轻松匹配到新场景&#xff0c;从而提…

目标检测之YOLOV11谈谈OBB

引言&#xff1a;从轴对齐到定向边界框的范式转变 在计算机视觉领域&#xff0c;目标检测算法长期受限于轴对齐边界框&#xff08;AABB&#xff09;的固有缺陷——当面对航拍图像中的舰船、遥感影像中的建筑物或工业质检中的倾斜零件时&#xff0c;传统边界框会包含大量背景噪…

Vue2之生命周期

文章目录 Vue生命周期Vue生命周期钩子生命周期钩子小案例在created中获取数据在mounted中获取焦点 Vue生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09;什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出…

Web 架构之多租户(SaaS)系统设计要点

文章目录 一、多租户系统概述定义应用场景 二、设计要点1. 数据隔离独立数据库共享数据库&#xff0c;独立 Schema共享数据库&#xff0c;共享 Schema数据访问控制 2. 资源分配计算资源存储资源 3. 租户管理租户注册与注销租户信息管理 4. 安全与合规身份验证与授权数据加密 三…

【Clickhouse系列】索引

目录 1. 主键索引 (Primary Key Index) - 核心是稀疏索引 2. 跳数索引 (Data Skipping Indexes) - 二级索引 3. 关键总结与最佳实践&#xff1a; ClickHouse的索引设计哲学与其他传统OLTP数据库&#xff08;如MySQL&#xff09;有显著不同&#xff0c;它更侧重于高效扫描大数…

445场周赛

第一题&#xff1a;检查元素频次是否为质数 给你一个整数数组 nums。 如果数组中任一元素的 频次 是 质数&#xff0c;返回 true&#xff1b;否则&#xff0c;返回 false。 元素 x 的 频次 是它在数组中出现的次数。 质数是一个大于 1 的自然数&#xff0c;并且只有两个因数…

【SQL语法汇总】

读音:MySQL —— 卖舌口 MySQL 实际上是DBMS软件系统, 并非数据库。通过系统管理维护数据库,DBMS相当于用户和数据库之间的桥梁。 MySQL是一种关系型数据库, 类似excel,用行和列的关系组织数据数据。 操作关系型数据库的DBMS系统大多数用SQL来管理数据。 SQL是编程语言…

C++法则10:引用本身是一个“别名”(alias),一旦绑定到一个对象后,就不能再重新绑定到其他对象。

C法则10&#xff1a;引用本身是一个“别名”&#xff08;alias&#xff09;&#xff0c;一旦绑定到一个对象后&#xff0c;就不能再重新绑定到其他对象。 在C中&#xff0c;引用&#xff08;reference&#xff09;是一个已存在对象的别名。一旦引用被初始化绑定到一个对象&…

PHP 生成当月日期

一&#xff1a;按日期顺序排列的数组&#xff0c;而不是按周分组的二维数组 /*日期生成 *day: 日期数字 *date: 完整的日期字符串 (YYYY-MM-DD) *is_current_month: 是否属于当前月份 *is_prev_month: 是否是上个月的日期 *is_next_month: 是否是下个月的日期 *is_today: 是否是…