Scrapy入门

2023-11-04

Scrapy入门

上一节我们介绍了Scrapy 框架的基本架构、数据流过程和项目架构,对Scrapy有了初步的认识。接下来我们用 Scrapy 实现一个简单的项目,完成一遍 Scrapy 抓取流程。通过这个过程,我们可以对Scrapy的基本用法和原理有大体了解。

1.目标

本节要完成的目标如下。

  • 创建一个 Scrapy 项目,熟悉 Scrapy项目的创建流程。
  • 编写一个 Spider 来抓取站点和处理数据,了解 Spider的基本用法。
  • 初步了解Item Pipeline 的功能,将抓取的内容保存到MongoDB数据库。
  • 运行Scrapy 爬虫项目,了解 Scrapy 项目的运行流程。

这里我们以 Scrapy 推荐的官方练习项目为例进行实战演练,抓取的目标站点为 https://quotes.toscrape.com/,页面如图所示。

image-20221107193538824

这个站点包含了一系列名人名言、作者和标签,我们需要使用Scrapy将其中的内容爬取并保存下来。

2.准备工作

在开始之前,我们需要安装好Scrapy框架、MongoDB和PyMongo库,具体的安装参考流程如下:

  • Scrapy:使用pip命令进行安装
  • MongoDB:https://cuiqingcai.com/31070.html
  • PyMongo:使用pip命令进行安装

安装好这三部分之后,我们就可以正常使用 Scrapy 命令了,同时也可以使用PyMongo连接MongoDB数据库并写入数据了。

3.创建项目

首先我们需要创建一个Scrapy项目,可以直接用命令生成,项目名称可以叫作 scrapytutorial,创建命令如下:

scrapy startproject scrapytutorial

image-20221107223040585

运行完毕后,当前文件夹下会生成一个名为scrapytutorial的文件夹:

image-20221107223130728

使用Pycharm打开文件,文件夹结构如下所示:

image-20221107223917521

4.创建 Spider

Spider是自己定义的类,Scrapy 用它来从网页里抓取内容,并解析抓取的结果。不过这个类必须继承 Scrapy 提供的 Spider 类 scrapy.Spider,还要定义 Spider 的名称和起始 Request,以及怎样处理爬取后的结果的方法。

也可以使用命令行创建一个 Spider。比如要生成 Quotes 这个 Spider,可以执行如下命令:

cd scrapytutorial
scrapy genspider quotes quotes.toscrape.com

image-20221107233526324

进人刚才创建的scrapytutorial 文件夹,然后执行genspider 命令。第一个参数是 Spider的名称,第二个参数是网站域名。执行完毕后,spiders 文件夹中多了一个 quotes.py,它就是刚刚创建的Spider,我们再把start_urls中的http协议改成https,最终代码如下所示:

import scrapy


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

    def parse(self, response):
        pass

这个QuotesSpider 就是刚才命令行自动创建的 Spider,它继承了 scrapy 的Spider类,QuotesSpitder有3个属性,分别为name、allowed_domains 和 start_urls,还有一个方法parse。

  • name是每个项目唯一的名字,用来区分不同的Spider。
  • allowed_domains是允许爬取的域名,如果初始或后续的请求链接不是这个域名下的,则请求链接会被过滤掉。
  • start_urls包含了 Spider 在启动时爬取的URL列表,初始请求是由它来定义的。
  • parse是 Spider的一个方法。在默认情况下,start_urls里面的链接构成的请求完成下载后,parse 方法就会被调用,返回的响应就会作为唯一的参数传递给 parse方法。该方法负责解析返回的响应、提取数据或者进一步生成要处理的请求。

5.创建 Item

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

创建Item 需要继承scrapy的Item类,并且定义类型为Field的字段,这个字段就是我们要爬取的字段。

那我们需要爬哪些字段呢?观察目标网站,我们可以获取到的内容有下面几项。

  • text:文本,即每条名言的内容,是一个字符串。
  • author:作者,即每条名言的作者,是一个字符串。
  • tags:标签,即每条名言的标签,是字符串组成的列表。

这样的话,每条爬取数据就包含这3个字段,那么我们就可以定义对应的tem,此时将items.py修改如下:

import scrapy

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

这里我们声明了QuoteItem,继承了Item类,然后使用 Field定义了3个字段,接下来爬取时我们会使用到这个Item。

6.解析 Response

前面我们看到,parse 方法的参数 response 是 start_urls 里面的链接爬取后的结果,即页面请求后得到的 Response,Scrapy 将其转化为了一个数据对象,里面包含了页面请求后得到的Response Status、Body 等内容。所以在parse方法中,我们可以直接对response 变量包含的内容进行解析,比如浏览请求结果的网页源代码,进一步分析源代码内容,或者找出结果中的链接而得到下一个请求。

我们可以看到网页中既有我们想要的结果,又有下一页的链接,这两部分内容我们都要进行处理。

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

我们可以使用CSS选择器或XPath选择器进行提取,这个过程我们可以直接借助response的css或 xpath 方法实现,这都是 Scrapy给我们封装好的方法,直接调用即可。

在这里我们使用CSS选择器进行选择,可以将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 .tags::text').extract()

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

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

7.使用Item

上文我们已经定义了QuoteItem,接下来就要使用它了。

我们可以把 ltem理解为一个字典,和字典还不太相同,其本质是一个类,所以在使用的时候需要实例化。实例化之后,我们依次用刚才解析的结果赋值 Item的每一个字段,最后将Item 返回。

QuotesSpider的改写如下:

import scrapy
from 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 .tags::text').extract()
            yield item

如此一来,首页的所有内容就被解析出来并被赋值成了一个个QuoteItem了,每个Quoteltem就代表一条名言,包含名言的内容、作者和标签。

8.后续Request

上面的操作实现了从首页抓取内容,如果运行它,我们其实已经可以从首页提取到所有quote信息并将其转化为一个个QuoteItem 对象了。

但是,这样还不够,下一页的内容该如何抓取呢?这就需要我们从当前页面中找到信息来生成下一个Request,利用同样的方式进行请求并解析就好了。那再下一页呢?也是一样的原理,我们可以在下一个页面里找到信息再构造再下一个Request。这样循环往复迭代,从而实现整站的爬取。

我们将刚才的页面拉到最底部,如图所示。

image-20221108234216407

这里我们发现有一个Next按钮,查看一下源代码,可以看到它的链接是/page/2/,实际上全链接就是 https://quotes.toscrape.com/page/2,通过这个链接我们就可以构造下一个Request了。

构造Request时需要用到scrapy的Request 类。这里我们传递两个参数,分别是url和 callback,这两个参数的说明如下。

  • url:目标页面的链接。
  • callback:回调方法,当指定了该回调方法的Request完成下载之后,获取Response,Engine会将该Response 作为参数传递给这个回调方法。回调方法进行Response的解析生成一个或多个Item 或 Request,比如上文的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)进行提取,其中 attr 代表提取节点的属性,href 则为要提取的属性名,然后再下一步调用extract_first方法获取内容。

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

第三行代码通过url和callback变量构造了一个新的Request,回调方法callback依然使用parse方法。这个 Request 执行完成后,其对应的Response 会重新经过parse方法处理,得到第二页的解析结果,然后以此类推,生成第二页的下一页,也就是第三页的请求。这样爬虫就进入了一个循环,直到最后一页。

通过几行代码,我们就轻松实现了一个抓取循环,将每个页面的结果抓取下来了。

现在,改写后的整个Spider类如下所示:

import scrapy
from 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 .tags::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())

可以看到整个站点的抓取逻辑就轻松完成了,不需要再去编写怎样发送Request,不需要去关心异常处理,因为这些工作Scrapy都帮我们完成了,我们只需要关注Spider本身的抓取和提取逻辑即可。

9.运行

接下来就是运行项目了,点击终端,输入命令:

scrapy crawl quotes

image-20221109113745605

就可以看到Scrapy的运行结果了:

image-20221109115404682

image-20221109115439332

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

首先,Scrapy 输出了当前的版本号以及正在启动的项目名称。然后输出了当前 settings.py 中一些重写后的配置。接着输出了当前所应用的Middlewares和Item Pipelines。 Middlewares和 Item Pipelines都沿用了Scrapy的默认配置,我们可以在 settings.py中配置它们的开启和关闭,后文会对它们的用法进行讲解。

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

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

整个Scapy程序成功运行。我们通过非常简单的代码就完成了一个站点内容的爬取,所有的名言都被我们抓取下来了。

10.保存到文件

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

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

scrapy crawl quotes -o quotes.json

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

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

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

Feed Exports支持从输出格式还有很多,例如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来完成。

11.使用Item Pipeline

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

ltem 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 MongoDBPipeline(object):
    def _init_(self, connection_string, database):
        self.connection_string = connection_string
        self.database = database

    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            connection_string=crawler.settings.get('MONGODB_CONNECTION_STRING'),
            database=crawler.settings.get('MONCODB_DATABASE')
        )

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

    def process_item(self, item, spider):
        name = item._class_._name_
        self.db[name].insert_one(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方法则执行了数据插入操作,这里直接调用 insert_one 方法传入item对象即可将数据存储到 MongoDB。

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

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

ITEM_PIPELINES = {
    'scrapytutorial.pipelines.TextPipeline': 300,
    'scrapytutorial.pipelines.MongoDBPipeline': 400,
}
MONGODB_CONNECTION_STRING = 'localhost'
MONGODB_DATABASE = 'scrapytutorial'

这里我们声明了 ITEM_PIPELINES 字典,键名是 Pipeline 的类名称,健值是调用优先级,是一个数字,数字越小则对应的Pipeline 越先被调用,另外我们声明了MongoDB的连接字符串和存储的数据库名称。

再重新执行爬取,命令还是一样的:

scrapy crawl quotes

爬取结束后,我们可以看到MongoDB中创建了一个 scrapytutorial的数据库和QuoteItem的表,内容如图所示。

image-20221109192010015

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scrapy入门 的相关文章

  • 将 Tor 代理与 scrapy 一起使用

    我需要帮助在 Ubuntu 中设置 Tor 并在 scrapy 框架中使用它 我做了一些研究并找到了这个指南 class RetryChangeProxyMiddleware RetryMiddleware def retry self r
  • 从 Django 调用 Scrapy Spider

    我有一个项目 在同一工作区中包含 django 和 scrapy 文件夹 my project django project django project settings py app1 app2 manage py scrapy pro
  • Scrapy中如何控制yield的顺序

    帮助 阅读下面的scrapy代码和爬虫的结果 我想从中抓取一些数据http china fathom info data data json http china fathom info data data json 并且仅Scrapy被允
  • Scrapy 使用带有规则的 start_requests

    我找不到任何使用 start requests 与规则的解决方案 我也没有在互联网上看到任何关于这两个的示例 我的目的很简单 我想重新定义 start request 函数以获得捕获请求期间所有异常的能力 并在请求中使用元 这是我的蜘蛛的代
  • 我有 12000 个已知 URL,用 Python 抓取它们的最快方法是什么?

    因此 我有一个从数据库中提取的 URL 列表 我需要抓取并解析每个 URL 的 JSON 响应 某些 URL 返回 null 而其他 URL 返回发送到 csv 文件的信息 我目前正在使用Scrapy 但是抓取这12000个URL大约需要4
  • 为什么我的 Scrapy 中的输入/输出处理器不工作?

    我正在努力追随本教程 http doc scrapy org en 1 1 intro tutorial html 我想要我的desc字段是标准化为单个空格且大写的单个字符串 dmoz spider py import scrapy fro
  • Scrapy Python Craigslist Scraper

    我正在尝试使用 Craigslist 分类广告Scrapy提取待售物品 我能够提取日期 帖子标题和帖子 URL但提取时遇到问题price 由于某种原因 当前代码提取all的价格 但是当我删除 在价格范围之前查找价格字段返回为空 有人可以查看
  • 在同一进程中多次运行Scrapy

    我有一个网址列表 我想抓取其中的每一个 请注意 将此数组添加为start urls不是我正在寻找的行为 我希望它在单独的爬网会话中一一运行 我想在同一个进程中多次运行Scrapy 我想将 Scrapy 作为脚本运行 如常见做法 https
  • Scrapy FakeUserAgentError:获取浏览器时发生错误

    我使用 Scrapy FakeUserAgent 并在我的 Linux 服务器上不断收到此错误 Traceback most recent call last File usr local lib64 python2 7 site pack
  • Scrapy 仅抓取每个页面的第一个结果

    我目前正在尝试运行以下代码 但它只保留每个页面的第一个结果 知道可能是什么问题吗 from scrapy contrib spiders import CrawlSpider Rule from scrapy contrib linkext
  • 如何使用scrapy Selector获取节点的innerHTML?

    假设有一些 html 片段 例如 a text in a b text in b b a
  • Selenium 与 scrapy 的动态页面

    我正在尝试使用 scrapy 从网页中抓取产品信息 我要抓取的网页如下所示 从包含 10 个产品的 Product list 页面开始 单击 下一步 按钮将加载接下来的 10 个产品 两个页面之间的 URL 不会改变 我使用 LinkExt
  • Python Scrapy:allowed_domains从数据库添加新域

    我需要向 allowed domains 添加更多域 因此我没有收到 已过滤的异地请求 我的应用程序获取从数据库获取的网址 因此我无法手动添加它们 我试图覆盖蜘蛛init 像这样 def init self super CrawlSpide
  • Scrapy仅抓取网站的一部分

    您好 我有以下代码来扫描给定站点中的所有链接 from scrapy item import Field Item from scrapy contrib spiders import CrawlSpider Rule from scrap
  • 如何更改 scrapy view 命令使用的浏览器?

    如何更改 scrapy shell 中 view response 命令使用的浏览器 我的机器上默认使用 safari 但我希望它使用 chrome 因为 chrome 中的开发工具更好 As eLRuLL https stackoverf
  • 如何添加剧作家的等待时间

    我正在将 scrapy 与 playwright 集成 但发现自己在单击后添加计时器时遇到困难 因此 当我点击后截取页面的屏幕截图时 它仍然挂在登录页面上 如何集成计时器以便页面等待几秒钟直到页面加载 选择器 onetrust close
  • 我可以在不使用 python 打开浏览器的情况下将 selenium 与 Scrapy 一起使用吗

    我想用 scrapy 和 python 进行一些网络爬行 我从互联网上发现了一些代码示例 其中他们将 selenium 与 scrapy 一起使用 我不太了解selenium但只知道它会自动执行一些网络任务 浏览器实际上会打开并执行一些操作
  • 如何从当前项目向 scrapyd 添加新服务

    我试图同时运行多个蜘蛛 并在 scrapy 中制作了自己的自定义命令 现在我尝试通过 srapyd 运行该命令 我尝试将其作为新服务添加到我的 scrapd conf 中 但它抛出一个错误 指出没有这样的模块 Failed to load
  • 如何使用scrapy获取某人的关注者以及Instagram照片下的评论?

    正如您所看到的 以下 json 包含关注者数量以及评论数量 但是我如何访问每个评论中的数据以及关注者 ID 以便我可以爬取它们 logging page id profilePage 20327023 user biography null
  • Scrapy - 如何抓取网站并将数据存储在 Microsoft SQL Server 数据库中?

    我正在尝试从我们公司创建的网站中提取内容 我在 MSSQL Server 中为 Scrapy 数据创建了一个表 我还设置了 Scrapy 并配置了 Python 来抓取和提取网页数据 我的问题是 如何将Scrapy爬取的数据导出到我本地的M

随机推荐

  • 有空就看看的leetcode3——整数反转(c++版)

    有空就看看的leetcode3 整数反转 c 版 学习前言 题目 解法 学习前言 考试好难啊 题目 给出一个 32 位的有符号整数 你需要将这个整数中每位上的数字进行反转 示例 1 输入 123 输出 321 示例 2 输入 123 输出
  • Pytorch基础(十)——优化器(SGD,Adagrad,RMSprop,Adam,LBFGS等)

    一 概念 Pytorch中优化器的目的 将损失函数计算出的差值Loss减小 优化过程 优化器计算网络参数的梯度 然后使用一定的算法策略来对参数进行计算 用新的参数来重新进行训练 最终降低Loss 其中官网提供了13种优化算法 其中主要的有5
  • Java 中的 IO 和 NIO

    IO 与 NIO 区别 Java IO Java IO 工作流程 NIO Java NIO 工作流程 总结 Java IO IO 面向字节流 是阻塞的 Java IO 中读取数据和写入数据都是面向流 Stream 即当从流中读取 写入数据的
  • @Cacheable实现自定义过期时间的redis缓存

    Cacheable用法 接口运行的结果会自动存入缓存中 下次接口再传入相同的参数查询就直接从缓存中取 如果下次传入的参数不相同 就会再进行缓存 这两个缓存没有关系 是不同的key cacheNames 用来指定缓存组件的名字 key 缓存数
  • 如何解决错误:AttributeError: module ‘tensorflow’ has no attribute ‘AUTO_REUSE’

    应该是tf版本原因 加入compat v1即可 reuse tf compat v1 AUTO REUSE 亲测可行
  • C++左值与右值の深思——万能引用与完美转发

    目录 传统艺能 左值与右值 左 右值引用 意义与应用 左值引用的缺陷 移动语义 移动构造与拷贝构造的区别 编译器优化 移动赋值 移动赋值和赋值重载的区别 容器优化 右值引用引用左值 容器优化 万能引用 完美转发 使用场景 传统艺能 小编是双
  • 程序员最爱用的在线代码编辑器合集,哪款是你的最爱?

    程序员最爱用的在线 在线IDE 分享合集 有没有你最爱用的 TitanIDE 首当其冲 TitanIDE 云原生集成开发环境 打开浏览器即可编码 快捷方便 最主要的优势概括为以下几点 1 多内核支持 VSCode Jetbrains IDE
  • 【OS命令注入01】常见OS命令执行函数及其利用(system、exec、passthru、popen、shell_exec及反引号结构)

    目录 1 OS命令注入概述 2 常见可注入函数及利用方法 2 1 system 函数 2 2 exec 函数 2 3 passthru 函数 2 4 popen 函数 2 5 shell exec及反引号结构 3 防御 4 总结 1 OS命
  • anaconda使用笔记(包括pip命令)

    anaconda使用笔记 包括pip命令 1 conda命令 conda命令使用方式 方式一 直接打开Anaconda Prompt即可 方式二 打开anaconda 然后在environment中选择你用的环境 点击运行图标 选择Open
  • ajax请求图片_带你完成第一个爬虫,简单爬取百度图片

    大家好 我是润森 什么是爬虫 网络爬虫 又被称为网页蜘蛛 网络机器人 在FOAF社区中间 更经常的称为网页追逐者 是一种按照一定的规则 自动地抓取万维网信息的程序或者脚本 另外一些不常使用的名字还有蚂蚁 自动索引 模拟程序或者蠕虫 来源 百
  • 华为数据之道

    由华为董事 质量与流程IT总裁 CIO陶景文 作序推荐 华为质量与流程IT 华为云 华为大学 联合出品 总结华为公司数据治理 数字化转型方面的实践经验 从技术 流程 管理等多个维度系统讲解华为数据治理和数字化转型的著作 华为是一家超大型企业
  • CTFHub

    0x00 前言 CTFHub 专注网络安全 信息安全 白帽子技术的在线学习 实训平台 提供优质的赛事及学习服务 拥有完善的题目环境及配套 writeup 降低 CTF 学习入门门槛 快速帮助选手成长 跟随主流比赛潮流 0x01 题目描述 过
  • QDockWidget详解(二)

    上次在 QDockWidget详解文章中介绍了一些有关QDockWidget的基础用法 今天继续来讲QDockWidget的用法 自定义标题栏 如果不想使用QDockWidget自带的标题栏 那么可以通过 void QDockWidget
  • 阿里云原生大数据计算服务maxcompute学习体验

    这两天有兴趣学习了下阿里的maxcompute大数据 随便谈谈自己的感受 一 感受 阿里云相关的产品线太多了 热门产品一页已经放不下了 正因为东西太多给人一种杂乱的感觉 也可能这是给技术人员用的 所以不用太讲客户体验 反正给我的体验就不太好
  • 五、数据仓库详细介绍(建模)实践篇

    1 数仓建模在数仓建设过程中的位置 这张截图源自之前从 0 到 1 建设数据仓库的经验总结 采用的是瀑布模式的展现方式 但实际操作中经常会使用螺旋迭代模式 因为很难有人能够一步到位的考虑清楚所有细节 通过业务调研我们熟悉了相关业务过程 需求
  • 2023-Python实现巨潮资讯网数据采集

    目录 1 目标网址 2 接口分析调试 3 代码实现 学习记录 巨潮资讯网数据采集 1 目标网址 网页 深证信数据服务平台 巨潮资讯 gt 网行情中心 网页 http webapi cninfo com cn marketDataDate 数
  • 寒假小复习5

    插入排序 public class Insert public static void main String args int nums 12 4 6 2 66 1 4 for int i 1 i lt nums length i int
  • 【华为OD机试 python】新员工座位安排系统【 2023 Q1 A卷

    华为OD机试 题目列表 2023Q1 点这里 2023华为OD机试 刷题指南 点这里 题目描述 工位由序列F1 F2 Fn组成 Fi值为0 1或2 其中0代表空置 1代表有人 2代表障碍物 1 某一空位的友好度为左右连续老员工数之和 2 为
  • vue3 element-plus 表格中必填项展示的星号的前后位置设置

    情况一 必填项的星号在前面 情况图片展示 实现方法 直接使用表单规则校验来实现 注意 规则校验一定要绑定prop 代码展示 html
  • Scrapy入门

    文章目录 Scrapy入门 1 目标 2 准备工作 3 创建项目 4 创建 Spider 5 创建 Item 6 解析 Response 7 使用Item 8 后续Request 9 运行 10 保存到文件 11 使用Item Pipeli