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入门 的相关文章

  • Scrapy、privoxy 和 Tor:SocketError:[Errno 61] 连接被拒绝

    我将 Scrapy 与 Privoxy 和 Tor 一起使用 这是我之前的问题Scrapy 与 Privoxy 和 Tor 如何更新 IP https stackoverflow com questions 45009940 scrapy
  • 如何在程序中向scrapy爬虫传递参数?

    我是 python 和 scrapy 的新手 我用的是这个博客的方法以编程方式运行多个 scrapy 蜘蛛 http kirankoduru github io python multiple scrapy spiders html在烧瓶应
  • 网页抓取中如何获取重定向的URL?

    我想要的只是请求实际 url 后重定向的 url 这是实际的网址https metric picodi net us r 19761 当我使用此 url 在浏览器上按 Enter 键时 它会将我重定向到这样的 url https www o
  • 如何将抓取的项目放入 Pyqt5 小部件中?

    我正在尝试为 Scrapy 爬虫制作一个简单的 GUI 用户可以按 开始 按钮来运行抓取并在 textBrowser 或其他 qt 小部件 请告知 中查看抓取的结果 我的蜘蛛 import scrapy json class CarSpid
  • 使用 scrapy 抓取多个页面

    我正在尝试使用 scrapy 抓取多个网页 页面的链接如下 http www example com id some number 在下一页中 末尾的数字减少了1 所以我正在尝试构建一个蜘蛛 它可以导航到其他页面并抓取它们 我的代码如下 i
  • 将 Tor 与 scrapy 框架结合使用

    我正在尝试抓取网站 该网站足够复杂以阻止机器人 我的意思是它只允许几个请求 之后 Scrapy 挂起 问题1 有没有办法 如果Scrapy挂起 我可以从同一点重新启动我的爬行过程 为了摆脱这个问题 我这样写了我的设置文件 BOT NAME
  • 如何使用PyCharm调试Scrapy项目

    我正在使用 Python 2 7 开发 Scrapy 0 20 我发现 PyCharm 有一个很好的 Python 调试器 我想用它来测试我的 Scrapy 蜘蛛 有人知道该怎么做吗 我尝试过的 Actually I tried to ru
  • 如何在Scrapy中迭代div?

    这可能是一个非常微不足道的问题 但我是 Scrapy 的新手 我试图找到问题的解决方案 但我只是看不出这段代码有什么问题 我的目标是废弃给定网站上的所有歌剧节目 每个节目的数据都位于一个具有 row fluid row performanc
  • 我有 12000 个已知 URL,用 Python 抓取它们的最快方法是什么?

    因此 我有一个从数据库中提取的 URL 列表 我需要抓取并解析每个 URL 的 JSON 响应 某些 URL 返回 null 而其他 URL 返回发送到 csv 文件的信息 我目前正在使用Scrapy 但是抓取这12000个URL大约需要4
  • Scrapy - 抓取时发现的抓取链接

    我只能假设这是 Scrapy 中最基本的事情之一 但我就是不知道如何去做 基本上 我会抓取一页来获取包含本周更新的网址列表 然后我需要一一进入这些网址并从中获取信息 我目前已经设置了两个刮刀 并且它们可以完美地手动工作 因此 我首先从第一个
  • Scrapy Python Craigslist Scraper

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

    我在抓取网站时收到来自服务器的 302 响应 2014 04 01 21 31 51 0200 ahrefs h DEBUG Redirecting 302 to
  • Scrapy文件下载如何使用自定义文件名

    For my scrapy http doc scrapy org index html我目前正在使用的项目文件管道 https doc scrapy org en latest topics media pipeline html scr
  • 设置restrict_xpaths设置后出现UnicodeEncodeError

    我是 python 和 scrapy 的新手 将restrict xpaths 设置设置为 table class lista 后 我收到了以下回溯 奇怪的是 通过使用其他 xpath 规则 爬虫可以正常工作 Traceback most
  • 访问 Scrapy 内的 django 模型

    是否可以在 Scrapy 管道内访问我的 django 模型 以便我可以将抓取的数据直接保存到我的模型中 我见过this https scrapy readthedocs org en latest topics djangoitem ht
  • Scrapy 仅抓取每个页面的第一个结果

    我目前正在尝试运行以下代码 但它只保留每个页面的第一个结果 知道可能是什么问题吗 from scrapy contrib spiders import CrawlSpider Rule from scrapy contrib linkext
  • 如何使用XPath选择非空段落?

    我想要抓取的网页具有类似的结构 每个都有一个段落是一个问题 一个段落是一个答案 我想抓取每个问题和答案并将它们存储在两个项目中 问题是 在某些页面上 问题和答案分别是 xxx p 1 and xxx p 2 但在其他页面上 xxx p 1
  • Scrapy:AttributeError:“列表”对象没有属性“iteritems”

    这是我关于堆栈溢出的第一个问题 最近想用linkedin 刮刀 https github com junks linkedInScraper 所以我下载并指示 scrapycrawl linkedin com 并收到以下错误消息 供您参考
  • XPath:通过当前节点属性选择当前和下一个节点的文本

    首先 这是从我之前的问题 https stackoverflow com questions 5202187 xpath select current and next nodes text by current node attribut
  • 如何更改 scrapy view 命令使用的浏览器?

    如何更改 scrapy shell 中 view response 命令使用的浏览器 我的机器上默认使用 safari 但我希望它使用 chrome 因为 chrome 中的开发工具更好 As eLRuLL https stackoverf

随机推荐

  • 有空就看看的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