15.2 Scrapy 入门

目录

一. 目标

二. 准备工作

三. 开始入门

1. 创建项目

2. 创建 Spider 

3. 创建 Item   

4. 解析 Response

5. 使用 Item

6. 后续 Request

7. 运行

8. 保存文件

9. 使用 Item Pipeline


一. 目标

        以一个目标例子来实战理解。目标如下:(1)创建一个 Scrapy 项目。(2)创建一个 Spider 来抓取站点和处理数据。(3)通过命令行将抓取的内容导出。(4)将抓取的内容保存到 MongoDB 数据库。

        抓取的目标站点为:Quotes to Scrape,要爬取该网站所以框中的信息。以下为网站首尾部分内容:

二. 准备工作

        安装好 Scrapy、MongoDB 和 pymongo 库。MongoDB 和 pymongo 库的安装见4.5 MongoDB 文档存储-CSDN博客。

三. 开始入门

1. 创建项目

        直接用命令生成。如果你想要将项目放置在特定目录下,则在特定目录 cmd 命令。例如我在这个目录下 cmd。(注:如果 cmd 是在一个 python 项目中会影响引入、会报错,错误见:15.0 Scrapy 使用中出现的错误分享-CSDN博客)

        之后在命令框中输入以下命令:

scrapy startproject 项目名称
例:scrapy startproject tutorial

         会出现一个 tutorial 文件夹,完全打开之后如下所示:

        在 pycharm 中

对此文件夹结构做出解释:

tutorial    # scrapytutorial文件夹
    tutorial         # 项目的模块,引入的时候需要从这里引入(此文件与 .idea同一目录时)
        spiders         # 放置 Spiders 的文件夹
            __init__.py
        __init__.py    
        items.py     # Items 的定义,定义爬取的数据结构
        middlewares.py   # Middlewares 的定义,定义爬取时的中间件
        pipelines.py       # Pipelines 的定义,定义数据管道
        settings.py       # 配置文件
    scrapy.cfg     # Scrapy 部署时的配置文件

2. 创建 Spider 

        Spider 是自己定义的类,Scrapy 用它来从网页里抓取内容,并解析抓取的结果。

        在 tutorial 文件夹中 cmd 进入,输入命令:

scrapy genspider Spider程序名 域名
例如:scrapy genspider quotes quotes.toscrape.com

        之后在 spiders 文件中就会出现 quotes.py,也会多出__pycache__文件夹。

        在 quptes.py 中

import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"    # 每个项目唯一名字,用来区分不同的 Spider
    allowed_domains = ["quotes.toscrape.com"]    # 允许爬取的域名
    start_urls = ["http://quotes.toscrape.com/"]    # Spider在启动时爬取的 url列表

    def parse(self, response):    # Spider 的一个方法
        pass

        这个 QuotesSpider 类就是刚才命令行自动创建的 Spider,它继承了 Scrapy 提供的 Spider 类 scrapy.Spider,还有三个属性 ——name、allowed_domains 和 start_urls,还有一个方法 parse。

allowed_domains,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉。

start_urls,初始请求是由它来定义的。

parse,默认情况下,被调用时 start_urls 里面的链接构成的请求完成下载执行后,
返回的响应就会作为唯一的参数传递给这个函数。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求。

3. 创建 Item   

        Item 是保存爬取数据的容器,定义了爬取结果的数据结构。它的使用方法和字典类似。不过,相比字典,Item 多了额外的保护机制,可以避免拼写错误或者定义字段错误。

        创建 Item 需要继承 scrapy.Item 类,并且定义类型为 scrapy.Field 的字段(在 items.py 中可看到)。观察目标网站,我们可以获取到的内容有 text、author、tags。

        这样我们爬取的每条数据中都包含这3个字段,则我们就可以定义 Item,此时将 items.py修改如下:

import scrapy

class QuoteItem(scrapy.Item):
    text = scrapy.Field()
    author = scrapy.Field()
    tags = scrapy.Field()
    pass

        将类的名称修改为 QuoteItem,使用 Field 定义了三个字段,接下来爬取时我们会使用到这个 Item。

4. 解析 Response

        在前面的 Spider 中,parse() 方法的参数 response 是 start_urls 里面的链接爬取后的结果。所以在 parse() 方法中,我们可以直接对 response 变量包含的内容进行解析,比如浏览请求结果的网页源代码,或者进一步分析源代码内容,或者找出结果中的链接而得到下一个请求。

        首先看看网页结构,如下图所示。每一页都有多个 class 为 quote 的区块,每个区块内都包含 text、author、tags。那么我们先找出所有的 quote,然后提取每一个 quote 中的内容。

        提取的方式可以是 CSS 选择器或 XPath 选择器。在这里我们使用 CSS 选择器进行选择,可直接借助 response 的 css 方法或 xpath 方法实现。parse() 方法的改写如下所示:

def parse(self, response):
    quotes = response.css('.quote')
    for quote in quotes:
        text = quote.css('.text::text').extract_first()
        author = quote.css('.author::text').extract_first()
        tags = quote.css('.tags .tag::text').extract()

        这里首先利用 CSS 选择器选取所有的 quote,并将其赋值为 quotes 变量,然后利用 for 循环对每个 quote 遍历,解析每个 quote 的内容。

        对 text 来说,观察到它的 class 为 text,所以可以用.text 选择器来选取,这个结果实际上是整个带有标签的节点,要获取它的正文内容,可以加::text 来获取。这时的结果是长度为 1 的列表,所以还需要用 extract_first() 方法来获取第一个元素。而对于 tags 来说,由于我们要获取所有的标签,所以用 extract() 方法获取整个列表即可。

5. 使用 Item

        上文定义了 Item,接下来就要使用它了。Item 可以理解为一个字典,但其本身是一个类,所以在声明的时候需要实例化。然后依次用刚才解析的结果赋值 Item 的每一个字段,最后将 Item 返回即可。quotes.py修改如下:

import scrapy
from fifthScrapy.scrapytutorial.scrapytutorial.items import QuoteItem


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response):
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags .tag::text').extract()
            yield item

        这里可以看到我的引入很长,因为我是在 BookStudyCrawler 这个 python 项目中 fifthScrapy 文件夹下 cmd 的, .idea文件与 fifthScrapy 同级。

        这样,首页的所有内容被解析出来,并被赋值成了一个个 QuoteItem,每个都包含名言的内容、作者和标签。

        yield 可参考:python中yield的用法(生成器的讲解)-CSDN博客

6. 后续 Request

        上面的操作实现了从初始页面抓取内容。那么,下一页的内容该如何抓取?这就需要我们从当前页面中找到信息来生成下一个请求,然后在下一个请求的页面里找到信息再构造再下一个请求。这样循环往复迭代,从而实现整站的爬取。

        下拉网站到底部,检查,找到链接。

        可以发现它的链接是 /page/2/,实际上全链接就是:http://quotes.toscrape.com/page/2/。通过这个链接我们就可以构造下一个请求。

        构造请求时需要用到 scrapy.Request。这里我们传递两个参数 ——url 和 callback,这两个参数的说明如下。

  • url:它是请求链接。

  • callback:它是回调函数。当指定了该回调函数的请求完成之后,获取到响应,引擎会将该响应作为参数传递给这个回调函数。回调函数进行解析或生成下一个请求,回调函数如上文的 parse() 所示。

        由于 parse() 就是解析 text、author、tags 的方法,而下一页的结构和刚才已经解析的页面结构是一样的,所以我们可以再次使用 parse() 方法来做页面解析。

        接下来我们要做的就是利用选择器得到下一页链接并生成请求,在 parse() 方法后追加如下的代码:

next = response.css('.pager .next a::attr(href)').extract_first()
url = response.urljoin(next)
yield scrapy.Request(url=url, callback=self.parse)

        第一句代码首先通过 CSS 选择器获取下一个页面的链接,即要获取 a 超链接中的 href 属性。这里用到了::attr(href) 操作。然后再调用 extract_first() 方法获取内容。

        第二句代码调用了 urljoin() 方法,urljoin() 方法可以将相对 URL 构造成一个绝对的 URL。例如,获取到的下一页地址是 /page/2,urljoin() 方法处理后得到的结果就是:http://quotes.toscrape.com/page/2/。

        第三句代码通过 url 和 callback 变量构造了一个新的请求,回调函数 callback 依然使用 parse() 方法。这个请求完成后,响应会重新经过 parse 方法处理,得到第二页的解析结果,然后生成第二页的下一页,也就是第三页的请求。这样爬虫就进入了一个循环,直到最后一页。

        通过几行代码,我们就轻松实现了一个抓取循环,将每个页面的结果抓取下来了。现在,改写之后的整个 Spider 类如下所示:

import scrapy
from fifthScrapy.scrapytutorial.scrapytutorial.items import QuoteItem


class QuotesSpider(scrapy.Spider):
    name = "quotes"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/"]

    def parse(self, response, **kwargs):
        quotes = response.css('.quote')
        for quote in quotes:
            item = QuoteItem()
            item['text'] = quote.css('.text::text').extract_first()
            item['author'] = quote.css('.author::text').extract_first()
            item['tags'] = quote.css('.tags .tag::text').extract()
            yield item
        next = response.css('.pager .next a::attr(href)').extract_first()
        url = response.urljoin(next)
        yield scrapy.Request(url=url, callback=self.parse)

7. 运行

        接下来,cmd 进入项目目录 D:\study\bookStudyProject\tutorial,运行如下命令:

scrapy crawl quotes

就可以看到结果了,部分运行结果如下:

D:\study\bookStudyProject\tutorial>scrapy crawl quotes
2024-03-11 11:33:32 [scrapy.utils.log] INFO: Scrapy 2.8.0 started (bot: tutorial)    # 当前的版本号以及正在启动的项目名称。
2024-03-11 11:33:32 [scrapy.utils.log] INFO: Versions: lxml 4.9.3.0, libxml2 2.10.4, cssselect 1.1.0, parsel 1.6.0, w3lib 1.21.0, Twisted 22.10.0, Python 3.11.5 | packaged by Anaconda, Inc. | (main, Sep 11 2023, 13:26:23) [MSC v.1916 64 bit (AMD64)], pyOpenSSL 23.2.0 (OpenSSL 3.0.13 30 Jan 2024), cryptography 41.0.3, Platform Windows-10-10.0.19045-SP0
2024-03-11 11:33:32 [scrapy.crawler] INFO: Overridden settings:    # setting.py重写后的配置
{'BOT_NAME': 'tutorial',
 'FEED_EXPORT_ENCODING': 'utf-8',
 .........,
 'TWISTED_REACTOR': 'twisted.internet.asyncioreactor.AsyncioSelectorReactor'}
2024-03-11 11:33:32 [asyncio] DEBUG: Using selector: SelectSelector
........
2024-03-11 11:33:32 [scrapy.middleware] INFO: Enabled extensions:
['scrapy.extensions.corestats.CoreStats',
 'scrapy.extensions.telnet.TelnetConsole',
 'scrapy.extensions.logstats.LogStats']
2024-03-11 11:33:32 [scrapy.middleware] INFO: Enabled downloader middlewares:
['scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware',
...........
 'scrapy.downloadermiddlewares.stats.DownloaderStats']
2024-03-11 11:33:32 [scrapy.middleware] INFO: Enabled spider middlewares:
['scrapy.spidermiddlewares.httperror.HttpErrorMiddleware',
..........
 'scrapy.spidermiddlewares.depth.DepthMiddleware']
2024-03-11 11:33:32 [scrapy.middleware] INFO: Enabled item pipelines:
[]
2024-03-11 11:33:32 [scrapy.core.engine] INFO: Spider opened
......
2024-03-11 11:33:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/>
{'author': 'Albert Einstein',
 'tags': ['change', 'deep-thoughts', 'thinking', 'world'],
 'text': '“The world as we have created it is a process of our thinking. It '
         'cannot be changed without changing our thinking.”'}
2024-03-11 11:33:34 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/>
{'author': 'J.K. Rowling',
 'tags': ['abilities', 'choices'],
 'text': '“It is our choices, Harry, that show what we truly are, far more '
         'than our abilities.”'}
...........
2024-03-11 11:33:38 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/page/10/>
{'author': 'George R.R. Martin',
 'tags': ['books', 'mind'],
 'text': '“... a mind needs books as a sword needs a whetstone, if it is to '
         'keep its edge.”'}
2024-03-11 11:33:38 [scrapy.dupefilters] DEBUG: Filtered duplicate request: <GET https://quotes.toscrape.com/page/10/> - no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
2024-03-11 11:33:38 [scrapy.core.engine] INFO: Closing spider (finished)
2024-03-11 11:33:38 [scrapy.statscollectors] INFO: Dumping Scrapy stats:
{'downloader/request_bytes': 3000,
 'downloader/request_count': 11,
 'downloader/request_method_count/GET': 11,
 ......
 'scheduler/enqueued': 10,
 'scheduler/enqueued/memory': 10,
 'start_time': datetime.datetime(2024, 3, 11, 3, 33, 32, 859140)}
2024-03-11 11:33:38 [scrapy.core.engine] INFO: Spider closed (finished)

        这里只是部分运行结果,中间一些抓取结果已省略。

        首先,Scrapy 输出了当前的版本号以及正在启动的项目名称。接着输出了当前 settings.py 中一些重写后的配置。然后输出了当前所应用的 Middlewares 和 Pipelines。Middlewares 默认是启用的,可以在 settings.py 中修改。Pipelines 默认是空,同样也可以在 settings.py 中配置。后面会对它们进行讲解。

        接下来就是输出各个页面的抓取结果了,可以看到爬虫一边解析,一边翻页,直至将所有内容抓取完毕,然后终止。

        最后,Scrapy 输出了整个抓取过程的统计信息,如请求的字节数、请求次数、响应次数、完成原因等。

        整个 Scrapy 程序成功运行。我们通过非常简单的代码就完成了一个网站内容的爬取,这样相比之前一点点写程序简洁很多。

8. 保存文件

        运行完 Scrapy 输出结果后,我们只在控制台看到了。如果想保存结果该怎么办呢?

        要完成这个任务其实不需要任何额外的代码,Scrapy 提供的 Feed Exports 可以轻松将抓取结果输出。例如,我们想将上面的结果保存成 JSON 文件,可以执行如下命令:

scrapy crawl quotes -o quotes.json

        命令运行后,项目内多了一个 quotes.json 文件,文件包含了刚才抓取的所有内容,内容是 JSON 格式。

        另外我们还可以每一个 Item 输出一行 JSON,输出后缀为 jl,为 jsonline 的缩写,命令如下所示:

scrapy crawl quotes -o quotes.jl
或者:
scrapy crawl quotes -o quotes.jsonlines

        输出格式还支持很多种,例如 csv、xml、pickle、marshal 等,还支持 ftp、s3 等远程输出,另外还可以通过自定义 ItemExporter 来实现其他的输出。

        例如,下面命令对应的输出分别为 csv、xml、pickle、marshal 格式以及 ftp 远程输出:

scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv

        其中,ftp 输出需要正确配置用户名、密码、地址、输出路径,否则会报错。

        通过 Scrapy 提供的 Feed Exports,我们可以轻松地输出抓取结果到文件。对于一些小型项目来说,这应该足够了。不过如果想要更复杂的输出,如输出到数据库等,我们可以使用 Item Pileline 来完成。

9. 使用 Item Pipeline

        如果想进行更复杂的操作,如将结果保存到 MongoDB 数据库,或者筛选某些有用的 Item,则我们可以定义 Item Pipeline 来实现。

        Item Pipeline 为项目管道。当 Item 生成后,它会自动被送到 Item Pipeline 进行处理,我们常用 Item Pipeline 来做如下操作。

  • 清洗 HTML 数据
  • 验证爬取数据,检查爬取字段
  • 查重并丢弃重复内容
  • 将爬取结果储存到数据库

        要实现 Item Pipeline 很简单,只需要定义一个类并实现 process_item() 方法即可。启用 Item Pipeline 后,自动调用这个方Item Pipeline 会法。process_item() 方法必须返回包含数据的字典或 Item 对象,或者抛出 DropItem 异常。

        process_item() 方法有两个参数。一个参数是 item,每次 Spider 生成的 Item 都会作为参数传递过来。另一个参数是 spider,就是 Spider 的实例。

        接下来,我们实现一个 Item Pipeline,筛掉 text 长度大于 50 的 Item,并将结果保存到MongoDB。

        修改项目里的 pipelines.py 文件,之前用命令行自动生成的文件内容可以删掉,增加一个 TextPipeline 类,内容如下所示:

from scrapy.exceptions import DropItem


class TextPipeline(object):
    def __init__(self):
        self.limit = 50

    def process_item(self, item, spider):
        if item['text']:
            if len(item['text']) > self.limit:
                item['text'] = item['text'][0:self.limit].rstrip() + '...'
            return item
        else:
            return DropItem('Missing Text')

        这段代码在构造方法里定义了限制长度为 50,实现了 process_item() 方法,其参数是 item 和 spider。首先该方法判断 item 的 text 属性是否存在,如果不存在,则抛出 DropItem 异常;如果存在,再判断长度是否大于 50,如果大于,那就截断然后拼接省略号,再将 item 返回即可。

        接下来,我们将处理后的 item 存入 MongoDB,定义另外一个 Pipeline。同样在 pipelines.py 中,我们实现另一个类 MongoPipeline,内容如下所示:

import pymongo

class MongoPipeline(object):
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db

    @classmethod
    def from_crawler(cls, crawler):
        return cls(mongo_uri=crawler.settings.get('MONGO_URI'),    # 指定连接地址
            mongo_db=crawler.settings.get('MONGO_DB')    # 连接数据库名称
        )    

    def open_spider(self, spider):
        self.client = pymongo.MongoClient(self.mongo_uri)
        self.db = self.client[self.mongo_db]

    def process_item(self, item, spider):
        name = item.__class__.__name__
        self.db[name].insert(dict(item))
        return item

    def close_spider(self, spider):
        self.client.close()

MongoPipeline 类实现了 API 定义的另外几个方法。

  • from_crawler,这是一个类方法,用 @classmethod 标识,是一种依赖注入的方式,方法的参数就是 crawler,通过 crawler 这个我们可以拿到全局配置的每个配置信息,在全局配置 settings.py 中我们可以定义 MONGO_URI 和 MONGO_DB 来指定 MongoDB 连接需要的地址和数据库名称,拿到配置信息之后返回类对象即可。所以这个方法的定义主要是用来获取 settings.py 中的配置的。
  • open_spider,当 Spider 被开启时,这个方法被调用。在这里主要进行了一些初始化操作。
  • close_spider,当 Spider 被关闭时,这个方法会调用,在这里将数据库连接关闭。

最主要的 process_item() 方法则执行了数据插入操作。

定义好 TextPipeline 和 MongoPipeline 这两个类后,我们需要在 settings.py 中使用它们。MongoDB 的连接信息还需要定义。

我们在 settings.py 中加入如下内容:

ITEM_PIPELINES = {
   'tutorial.pipelines.TextPipeline': 300,
   'tutorial.pipelines.MongoPipeline': 400,
}
MONGO_URI='localhost'
MONGO_DB='tutorial'

        赋值 ITEM_PIPELINES 字典,键名是 Pipeline 的类名称,键值是调用优先级,是一个数字,数字越小则对应的 Pipeline 越先被调用。

        再重新执行爬取,命令如下所示:

scrapy crawl quotes

        爬取结束后,MongoDB (下载等见:4.5 MongoDB 文档存储-CSDN博客)中创建了一个 tutorial 的数据库、QuoteItem 的表,如下图所示:

        长的 text 已经被处理并追加了省略号,短的 text 保持不变,author 和 tags 也都相应保存。

        这个流程似乎比较复杂,入门的话多看看,先理解学会,与套公式一样。

       文章到此结束,本人新手,若有错误,欢迎指正;若有疑问,欢迎讨论。若文章对你有用,点个小赞鼓励一下,谢谢大家,一起加油吧!

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

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

相关文章

智能计算的基本原理——智能计算原理与实践【文末送书-36】

文章目录 智能计算的基本原理基本原理技术智能计算在实践中的应用 智能计算&#xff1a;原理与实践【文末送书-36】 随着科技的不断发展&#xff0c;智能计算成为引领时代的前沿技术之一。从传统的计算机模型到如今的人工智能系统&#xff0c;智能计算不仅深刻地改变着我们的生…

Python 查找PDF中的指定文本并高亮显示

在处理大量PDF文档时&#xff0c;有时我们需要快速找到特定的文本信息。本文将提供以下三个Python示例来帮助你在PDF文件中快速查找并高亮指定的文本。 查找并高亮PDF中所有的指定文本查找并高亮PDF某个区域内的指定文本使用正则表达式搜索指定文本并高亮 本文将用到国产第三方…

海豚调度系列之:任务类型——SPARK节点

海豚调度系列之&#xff1a;任务类型——SPARK节点 一、SPARK节点二、创建任务三、任务参数四、任务样例1.spark submit2.spark sql 五、注意事项&#xff1a; 一、SPARK节点 Spark 任务类型用于执行 Spark 应用。对于 Spark 节点&#xff0c;worker 支持两个不同类型的 spark…

前端vue-Taro框架中使用插件 ---pinyin 将城市树形分类

1.需求 当我做一个获取城市的功能的时候 我发向后端返回的数据 和我想i选要的相差太多 这样的在手机端可以滑动 并且 快捷选中的城市列表 目前的数据是这样的&#xff0c;就是一个城市数组 目前这样的数组 我要想显示我的页面实现功能是不行的 需要是树形结够 所以我前端…

真空泵系统数据采集远程监控解决方案

行业背景 半导体制造业可以说是现代电子工业的核心产业&#xff0c;广泛应用于计算机、通信、汽车、医疗等领域。而在半导体生产加工过程中&#xff0c;如刻蚀、 镀膜、 扩散、沉积、退火等环节&#xff0c;真空泵都是必不可少的关键设备&#xff0c;它可以构建稳定受控的真空…

指针【理论知识速成】(3)

一.指针的使用和传值调用&#xff1a; 在了解指针的传址调用前&#xff0c;先来额外了解一下 “传值调用” 1.传值调用&#xff1a; 对于来看这个帖子的你相信代码展示胜过千言万语 #include <stdio.h> #include<assert.h> int convert(int a, int b) {int c 0…

优维大模型解密:从提示词工程到场景应用 ,剑指AIOps的牛刀小试

莫名其妙的“涌现”袭来&#xff0c;就像是海上来路不明的诡异海啸&#xff0c;当很多人都在吹捧大模型时&#xff0c;优维则选择理性潜入深水区&#xff0c;掌握了大模型的来龙去脉&#xff0c;也在实际应用中获得产品经验方法论。 这篇文章旨在全面剖析优维科技在大模型应用…

算法思想总结:双指针算法

一、移动零 . - 力扣&#xff08;LeetCode&#xff09; 移动零 该题重要信息&#xff1a;1、保持非0元素的相对位置。2、原地对数组进行操作 思路&#xff1a;双指针算法 class Solution { public:void moveZeroes(vector<int>& nums){int nnums.size();for(int cur…

手把手写深度学习(23):视频扩散模型之Video DataLoader

手把手写深度学习(0)&#xff1a;专栏文章导航 前言&#xff1a;训练自己的视频扩散模型的第一步就是准备数据集&#xff0c;而且这个数据集是text-video或者image-video的多模态数据集&#xff0c;这篇博客手把手教读者如何写一个这样扩散模型的的Video DataLoader。 目录 准…

挑战杯 多目标跟踪算法 实时检测 - opencv 深度学习 机器视觉

文章目录 0 前言2 先上成果3 多目标跟踪的两种方法3.1 方法13.2 方法2 4 Tracking By Detecting的跟踪过程4.1 存在的问题4.2 基于轨迹预测的跟踪方式 5 训练代码6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习多目标跟踪 …

4G安卓核心板T310_紫光展锐平台方案

紫光展锐T310应用 DynamlQ架构 12nm 制程工艺&#xff0c;采用 1*Cortex-A753*Cortex-A55处理器&#xff0c;搭载Android11.0操作系统&#xff0c;主频最高达2.0GHz.此外&#xff0c;DynamlQ融入了AI神经网络技术&#xff0c;新增机器学习指令&#xff0c;让其在运算方面的机器…

绝对省事!多微信聚合聊天神器大揭秘!

在如今社交网络发达的时代&#xff0c;微信已成为人们生活中不可或缺的通讯工具。然而&#xff0c;对于拥有多个微信账号的用户来说&#xff0c;经常需要来回切换不同账号&#xff0c;给日常使用带来一定的不便。 那么&#xff0c;有没有一种办法能够让我们摆脱这种繁琐的操作…

掼蛋-掌握出牌权

掼蛋游戏中&#xff0c;出牌权往往能决定一局牌的走向&#xff0c;掌握出牌权可以主动控制局势。出牌权是指在每一轮的出牌环节中谁先出牌。出牌权的重要性主要体现在以下两个方面&#xff1a; 一、控制节奏 出牌权可以让我们主动控制游戏的节奏&#xff0c;可以根据自己的出牌…

Post请求出现Request header is too large

问题描述&#xff1a; 在做项目的时候&#xff0c;前端请求体太大的时候&#xff0c;出现Request header is too large问题&#xff0c;后端接口如下&#xff1a; 前端请求接口返回问题如下&#xff1a; 解决方案&#xff1a; 问题原因&#xff1a;这是因为我们在做Springboo…

BUG:RuntimeError: input.size(-1) must be equal to input_size. Expected 1, got 3

出现的bug为:RuntimeError: input.size(-1) must be equal to input_size. Expected 1, got 3 出现问题的截图: 问题产生原因:题主使用pytorch调用的nn.LSTM里面的input_size和外面的数据维度大小不对。问题代码如下: self.lstm nn.LSTM(input_size, hidden_size, num_laye…

计算机网络-第6章 应用层(2)

6.5 电子邮件 电子邮件&#xff0c;把邮件发送到收件人使用的邮件服务器&#xff0c;并放在其中的收件人邮箱中。最重要的两个标准&#xff1a;简单邮件传送协议SMTP&#xff0c;互联网文本报文格式。 SMTP只能传7位ASCII码邮件&#xff0c;93年提出互联网邮件扩充MIME。邮件…

关于YOLOv9去掉辅助分支脚本使用的一些说明。

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; B站链接&#xff1a;YOLOv9去除辅助训练分支&#xff01;_哔哩哔哩_bilibili 一、说明 在subbranch_removal.py脚本中&#xff0c;我们需要填入上方…

新西兰 eSIM 卡 ONE NZ充值、激活

新西兰One NZ 保号规则和费用 先说大家比较关注的保号条件和费用吧。 新买的卡有效期 720 天&#xff0c;能够充值续期&#xff0c;但是充值后的有效期反而变为 360 天&#xff08;用于保号的兄弟就快过期再充值&#xff09;如果到期后不去充值&#xff0c;账户将变为非活跃状…

SAP 工单CO02 TECO时检查的增强BADI:WORKORDER_UPDATE

需求&#xff1a;需要在CO02进行TECO时检查一下 第三代增强&#xff1a;BADI&#xff1a;WORKORDER_UPDATE中的REORG_STATUS_ACT_CHECK方法 第一步&#xff1a;SE19输入BADI&#xff0c;然后创建 填入名称&#xff1a;ZWORKORDER_UPDATE和描述 输入类名&#xff1a;ZCL_WORKORD…

C语言函数—自定义函数

如果库函数能干所有的事情&#xff0c;那还要程序员干什么&#xff1f; 所有更加重要的是自定义函数。 自定义函数和库函数一样&#xff0c;有函数名&#xff0c;返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。 这给程序员一个很大的发挥空间。 函数的组…