Python爬虫基础(五):使用scrapy框架

news2024/11/25 2:19:37

文章目录

  • 系列文章索引
  • 一、scrapy简介
    • 1、什么是scrapy
    • 2、scrapy安装
    • 3、scrapy架构组成
    • 4、scrapy工作原理
  • 二、scrapy基本使用
    • 1、创建项目
    • 2、创建爬虫文件
    • 3、(附)项目组成
    • 4、运行爬虫代码
      • (1)修改baidu.py
      • (2)robots文件
    • 5、response的属性和方法
    • 6、实战:获取百度的【百度一下】按钮的内容
    • 7、实战:获取汽车之家汽车价格表
  • 三、使用scrapy shell
    • 1、什么是scrapy shell
    • 2、安装ipython(非必须)
    • 3、使用scrapy shell
  • 四、实战:获取当当网商品数据
    • 1、初始化项目
    • 2、定义item文件
    • 3、爬取图片、名字、价格
    • 4、管道封装
      • (1)熟悉yield
      • (2)构造item对象并交给pipeline
      • (3)在settings.py中开启pipeline
      • (4)编辑pipeline.py
      • (5)执行,查看写入的json文件
    • 5、多条管道使用
      • (1)pipelines.py定义管道类
      • (2)settings.py开启管道
      • (5)执行,查看写入的json文件与图片
    • 6、获取多页数据
  • 五、实战:获取电影天堂不同页面的数据
    • 1、效果
    • 2、核心代码
  • 六、实战:使用CrawlSpider获取读书网的数据
    • 1、CrawlSpider简介
    • 2、创建项目
    • 3、定义item
    • 4、提取数据
    • 5、定义pipeline
    • 6、启动
    • 7、保存至mysql
  • 七、实战:发送post请求

系列文章索引

Python爬虫基础(一):urllib库的使用详解
Python爬虫基础(二):使用xpath与jsonpath解析爬取的数据
Python爬虫基础(三):使用Selenium动态加载网页
Python爬虫基础(四):使用更方便的requests库
Python爬虫基础(五):使用scrapy框架

一、scrapy简介

1、什么是scrapy

Scrapy 是一个为了抓取网页数据、提取结构性数据而编写的应用框架,该框架是封装的,包含 request (异步调度和处理)、下载器(多线程的 Downloader)、解析器(selector)和 twisted(异步处理)等。对于网站的内容爬取,其速度非常快捷。

2、scrapy安装

# 进入到python安装目录的Scripts目录
d:
cd D:\python\Scripts
# 安装 可以使用国内源
pip install scrapy

3、scrapy架构组成

(1)引擎:自动运行,无需关注,会自动组织所有的请求对象,分发给下载器。
(2)下载器:从引擎处获取到请求对象后,请求数据。
(3)spiders:spider类定义了如何爬取某个(或某些)网站。包括了爬取的动作(例如:是否跟进链接)以及如何从网页的内容中提取结构化数据(爬取item)。换句话说,Spider就是定义爬取的动作及分析某个网页的地方。
(4)调度器:有自己的调度规则,无需关注。
(5)管道(Item pipeline):最终处理数据的管道,会预留接口供我们处理数据。当Item在Spider中被收集之后,它将会被传递到Item pipeline,一些组件会按照一定的顺序执行对Item的处理。每个item pipeline组件是实现了简单方法的Python类,他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。

以下是item pipeline的一些典型应用:
(1)清理HTML数据,(2)验证爬取的数据(检查item包含某些字段),(3)查重(并丢弃),(4)将爬取结果保存到数据库中。

4、scrapy工作原理

spiders->scheduler(调度器)->scrapy engine(引擎)->downloader(下载器)->互联网进行下载
->下载后的数据从引擎到spiders->通过引擎xpath进行数据解析->使用pipeline对数据进行存储

在这里插入图片描述
在这里插入图片描述

二、scrapy基本使用

1、创建项目

进入到项目目录,打开cmd:

# 创建scrapy_test_001项目,项目名不能以数字、汉字开头
scrapy startproject scrapy_test

2、创建爬虫文件

要在spiders文件夹中去创建爬虫文件

# cd 项目的名字\项目的名字\spiders
cd scrapy_test\scrapy_test\spiders

创建爬虫文件,注意,不需要添加http协议了:

# scrapy genspider 爬虫文件的名字  要爬取网页
scrapy genspider baidu  www.baidu.com

此时,在spiders目录中,会生成一个baidu.py:
在这里插入图片描述
我们看一下baidu.py的内容:

import scrapy

class BaiduSpider(scrapy.Spider):
    # 爬虫的名字  用于运行爬虫的时候 使用的值
    name = "baidu"
    # 允许访问的域名
    allowed_domains = ["www.baidu.com"]
    # 起始的url地址  指的是第一次要访问的域名
    start_urls = ["https://www.baidu.com"]

    # 是执行了start_urls之后 执行的方法   方法中的response 就是返回的那个对象
    # 相当于 response = urllib.request.urlopen()
    #       response  = requests.get()
    def parse(self, response):
        pass

后续我们可以在parse方法中,对response进行处理,这就是最终爬取的结果。

3、(附)项目组成

在这里插入图片描述

4、运行爬虫代码

(1)修改baidu.py

在parse方法中,自定义输出:

def parse(self,response):
    print('输出正确!')

在spiders目录中,执行以下命令,就可以运行爬虫代码:

# scrapy crawl 爬虫的名字
scrapy crawl baidu

会输出很多内容,但是并没有我们打印的东西。

(2)robots文件

控制台中,打印出了百度的robots协议:
在这里插入图片描述

每个网站都会有一个robots君子协议,里面定义了哪些不允许爬取,我们看百度的robots:
https://www.baidu.com/robots.txt

在项目的settings.py文件中,默认是ROBOTSTXT_OBEY=True,表示遵循这个君子协议。

我们只需要将这一行注释掉:
在这里插入图片描述
此时我们再执行爬虫代码:

# scrapy crawl 爬虫的名字
scrapy crawl baidu

此时在命令行中,会打印出我们自定义的那句话了。

5、response的属性和方法

response.xpath(xpath_expression):根据XPath表达式选择并提取数据。
response.css(css_expression):根据CSS选择器选择并提取数据。
response.follow(url):根据给定的URL创建新的请求,并通过回调方法继续处理。
response.url:返回当前响应的URL。
response.status:返回当前响应的状态码。
response.headers:返回当前响应的头部信息。
response.body:返回当前响应的原始二进制内容。
response.text:返回当前响应的文本内容。
response.css(‘a::attr(href)’).getall():使用CSS选择器提取所有匹配的元素属性值。
response.xpath(‘//a/@href’).extract():使用XPath表达式提取所有匹配的元素属性值

6、实战:获取百度的【百度一下】按钮的内容

在这里插入图片描述

    def parse(self, response):
        print('=====================')
        input = response.xpath('//input[@id="su"]/@value')[0]
        print(input.extract()) # 百度一下
        print('=====================')

7、实战:获取汽车之家汽车价格表

在这里插入图片描述

import scrapy

class CarSpider(scrapy.Spider):
    name = 'car'
    allowed_domains = ['https://car.autohome.com.cn/price/brand-15.html']
    start_urls = ['https://car.autohome.com.cn/price/brand-15.html']

    def parse(self, response):
        print('=======================')
        name_list = response.xpath('//div[@class="main-title"]/a/text()')
        price_list = response.xpath('//div[@class="main-lever"]//span/span/text()')

        for i in range(len(name_list)):
            name = name_list[i].extract()
            price = price_list[i].extract()
            print(name,price)
        print('=======================')

三、使用scrapy shell

1、什么是scrapy shell

scrapy终端,是一个交互终端,供您在未启动spider的情况下尝试及调试您的爬取代码。 其本意是用来测试提取数据的代码,不过您可以将其作为正常的python终端,在上面测试任何的python代码。

该终端是用来测试xPath或css表达式,查看他们的工作方式及从爬取的网页中提取的数据。在编写您的spider时,该终端提供了交互性测试您的表达式代码的功能,免去了每次修改后运行spider的麻烦。一旦熟悉了scrapy终端后,您会发现其在开发和调试spider时发挥的巨大作用。

2、安装ipython(非必须)

# 进入到python安装目录的Scripts目录
d:
cd D:\python\Scripts
# 安装 可以使用国内源
pip install ipython

如果安装了 IPython,scrapy终端将使用 IPython (替代标准Python终端)。 IPython 终端与其他相比更为强大,提供智能的自动补全,高亮输出,及其他特性。

使用:命令行直接输入ipython,进入的新命令窗口自带高亮及自动补全:
在这里插入图片描述

3、使用scrapy shell

# 直接在window的终端中输入scrapy shell 域名
# 直接在命令终端(不需要进入python或者ipython终端),执行完毕之后,自动进入ipython终端
scrapy shell www.baidu.com

可以直接获取到response对象,可以直接在此进行调试。
在这里插入图片描述

四、实战:获取当当网商品数据

1、初始化项目

# 在自定义目录中创建项目
scrapy startproject scrapy_dangdang

# 创建爬虫文件
# cd 项目的名字\项目的名字\spiders
cd scrapy_dangdang\scrapy_dangdang\spiders

# scrapy genspider 爬虫文件的名字  要爬取网页
# 中国古典小说网址:http://category.dangdang.com/cp01.03.32.00.00.00.html
scrapy genspider dang http://category.dangdang.com/cp01.03.32.00.00.00.html

# 运行
scrapy crawl dang

2、定义item文件

在项目自动生成的item.py中,定义要爬取的数据格式:

import scrapy

class ScrapyDangdangItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 通俗的说就是你要下载的数据都有什么,固定写法:scrapy.Field()

    # 图片
    src = scrapy.Field()
    # 名字
    name = scrapy.Field()
    # 价格
    price = scrapy.Field()

3、爬取图片、名字、价格

在这里插入图片描述
我们先分析这三者的xpath:
拿到图片的xpath://ul[@id="component_59"]/li/a/img/@src 因为图片懒加载,应该取图片的data-original属性。
在这里插入图片描述
拿到标题的xpath://ul[@id="component_59"]/li/p[@class="name"]/a/@title
在这里插入图片描述
拿到价格的xpath://ul[@id="component_59"]/li/p[@class="price"]/span[1]/text()
在这里插入图片描述

import scrapy

class DangSpider(scrapy.Spider):
    name = "dang"
    allowed_domains = ["category.dangdang.com"]
    start_urls = ["http://category.dangdang.com/cp01.03.32.00.00.00.html"]

    def parse(self, response):
        #         src = //ul[@id="component_59"]/li/a/img/@src
        #         name = //ul[@id="component_59"]/li/p[@class="name"]/a/@title
        #         price = //ul[@id="component_59"]/li/p[@class="price"]/span[1]/text()
        #         所有的seletor的对象 都可以再次调用xpath方法
        li_list = response.xpath('//ul[@id="component_59"]/li')

        for li in li_list:
            src = li.xpath('./a/img/@data-original').extract_first()
            # 第一张图片和其他的图片的标签的属性是不一样的
            # 第一张图片的src是可以使用的  其他的图片的地址是data-original
            if src:
                src = src
            else:
                src = li.xpath('./a/img/@src').extract_first()

            name = li.xpath('./p[@class="name"]/a/@title').extract_first()
            price = li.xpath('./p[@class="price"]/span[1]/text()').extract_first()
            # 拿到所有信息
            print(src + name + price)

4、管道封装

(1)熟悉yield

带有tield的函数不再是一个普通函数,而是一个生成器generator,可用于迭代。

yield是一个类似return的关键字,迭代一次遇到yield时就返回yield后面(右边)的值。重点是:下一次迭代时,从上一次迭代器遇到的yield后面的代码(下一行)开始执行。

简单理解:yield就是return返回一个值,并且记住这个返回的位置,下次迭代就从这个位置后(下一行)开始。

(2)构造item对象并交给pipeline

上面我们已经获取到图片、名称和价格了,继续在parse方法中构造item对象并交给pipeline:

from scrapy_dangdang.items import ScrapyDangdangItem
            # 构造item对象
            book = ScrapyDangdangItem(src=src,name=name,price=price)

            # 获取一个book就将book交给pipelines
            yield book

(3)在settings.py中开启pipeline

管道可以有很多个 那么管道是有优先级的 优先级的范围是1到1000 值越小优先级越高。

ITEM_PIPELINES = {
    #  管道可以有很多个  那么管道是有优先级的  优先级的范围是1到1000   值越小优先级越高
   "scrapy_dangdang.pipelines.ScrapyDangdangPipeline": 300,
}

(4)编辑pipeline.py

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html

# useful for handling different item types with a single interface
from itemadapter import ItemAdapter

# 如果想使用管道的话 那么就必须在settings中开启管道
class ScrapyDangdangPipeline:
    # 在爬虫文件开始的之前就执行的一个方法 :open_spider
    def open_spider(self,spider):
        self.fp = open('book.json','w',encoding='utf-8')

    # 执行过程:process_item
    # item就是yield后面的book对象
    def process_item(self, item, spider):
        # 以下这种模式不推荐  因为每传递过来一个对象 那么就打开一次文件  对文件的操作过于频繁

        # # (1) write方法必须要写一个字符串 而不能是其他的对象
        # # (2) w模式 会每一个对象都打开一次文件 覆盖之前的内容
        # with open('book.json','a',encoding='utf-8')as fp:
        #     fp.write(str(item))

        self.fp.write(str(item))
        self.fp.write('\n')

        return item

    # 在爬虫文件执行完之后  执行的方法 : close_spider
    def close_spider(self,spider):
        self.fp.close()

(5)执行,查看写入的json文件

scrapy crawl dang

5、多条管道使用

(1)pipelines.py定义管道类

pipelines.py中可以定义多个类,直接写即可。
类中有三个默认的方法,可以直接使用。

import urllib.request
class ScrapyDangdangDownloadPipeline:
    def process_item(self, item, spider):
        url = 'http:' + item.get('src')
        filename = './books/' + item.get('name') + '.jpg'
        urllib.request.urlretrieve(url = url, filename= filename)
        # 有返回值
        return item

(2)settings.py开启管道

ITEM_PIPELINES = {
    #  管道可以有很多个  那么管道是有优先级的  优先级的范围是1到1000   值越小优先级越高
   "scrapy_dangdang.pipelines.ScrapyDangdangPipeline": 300,

   'scrapy_dangdang.pipelines.ScrapyDangdangDownloadPipeline':301
}

(5)执行,查看写入的json文件与图片

先在spiders下创建books目录。

# 执行
scrapy crawl dang

6、获取多页数据

import scrapy
from scrapy_dangdang.items import ScrapyDangdangItem


class DangSpider(scrapy.Spider):
    name = "dang"
    allowed_domains = ["category.dangdang.com"]
    start_urls = ["http://category.dangdang.com/cp01.03.32.00.00.00.html"]

    base_url = 'http://category.dangdang.com/cp'
    page = 1
    def parse(self, response):
		# 。。。省略


#       每一页的爬取的业务逻辑全都是一样的,所以我们只需要将执行的那个页的请求再次调用parse方法
# 就可以了
#         http://category.dangdang.com/pg2-cp01.03.32.00.00.00.html
#         http://category.dangdang.com/pg3-cp01.03.32.00.00.00.html
#         http://category.dangdang.com/pg4-cp01.03.32.00.00.00.html

        if self.page < 100:
            self.page = self.page + 1

            url = self.base_url + str(self.page) + '-cp01.03.32.00.00.00.html'

#             怎么去调用parse方法
#             scrapy.Request就是scrpay的get请求
#             url就是请求地址
#             callback是你要执行的那个函数  注意不需要加()
            yield scrapy.Request(url=url,callback=self.parse)


五、实战:获取电影天堂不同页面的数据

1、效果

获取电影天堂,第一页列表的电影名:
在这里插入图片描述
然后点击电影详情,再从第二页获取到详情中的图片:
在这里插入图片描述

2、核心代码

mv.py核心代码

import scrapy

from scrapy_movie_099.items import ScrapyMovie099Item

class MvSpider(scrapy.Spider):
    name = 'mv'
    allowed_domains = ['www.dygod.net']
    start_urls = ['https://www.dygod.net/html/gndy/china/index.html']

    def parse(self, response):
#         要第一个的名字 和 第二页的图片
        a_list = response.xpath('//div[@class="co_content8"]//td[2]//a[2]')

        for a in a_list:
            # 获取第一页的name 和 要点击的链接
            name = a.xpath('./text()').extract_first()
            href = a.xpath('./@href').extract_first()

            # 第二页的地址是
            url = 'https://www.dygod.net' + href

            # 对第二页的链接发起访问 并将name参数传入
            yield  scrapy.Request(url=url,callback=self.parse_second,meta={'name':name})

    def parse_second(self,response):
        # 注意 如果拿不到数据的情况下  一定检查你的xpath语法是否正确
        src = response.xpath('//div[@id="Zoom"]//img/@src').extract_first()
        # 接受到请求的那个meta参数的值
        name = response.meta['name']

        movie = ScrapyMovie099Item(src=src,name=name)

        yield movie

pipelines.py:

from itemadapter import ItemAdapter

class ScrapyMovie099Pipeline:

    def open_spider(self,spider):
        self.fp = open('movie.json','w',encoding='utf-8')

    def process_item(self, item, spider):

        self.fp.write(str(item))
        return item

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

settings.py中开启pipeline:

ITEM_PIPELINES = {
   'scrapy_movie_099.pipelines.ScrapyMovie099Pipeline': 300,
}

六、实战:使用CrawlSpider获取读书网的数据

1、CrawlSpider简介

CrawlSpider继承自scrapy.Spider,可以定义规则,再解析html内容的时候,可以根据链接规则提取出指定的链接,然后再向这些链接发送请求。

所以,如果有需要跟进链接的需求,就是爬取了网页之后,需要提取链接再次爬取,使用CrawlSpider是非常合适的。

提取链接常用语法
链接提取器,在这里就可以写规则提取指定链接:

scrapy.linkextractors.LinkExtractor(
	allow = (), # 正则表达式,提取符合正则的链接
	deny = (), # (不用)正则表达式 不提取符合正则的链接
	allow_domains = (), # (不用)允许的域名
	deny_domains = (), # (不用)不允许的域名
	restrict_xpaths = (), # xpath,提取符合xpath规则的链接
	restrict_css = () # 提取符合选择器规则的链接
)

# 使用实例
# 正则用法:
links = LinkExtractor(allow = r'list_23_\d+\.html')
# xpath:
links = LinkExtractor(restrict_xpaths = r'//div[@class="x"]')
# css用法:
links = LinkExtractor(restrict_css='.x')

# 提取链接
links.extract_links(response)

2、创建项目

# 创建项目:scrapy startproject 项目的名字
scrapy startproject readbook

# 创建爬虫文件
# cd 项目名字\项目名字\spiders
cd readbook/readbook/Spiders
# scrapy genspider -t crawl 爬虫文件的名字  爬取的域名
scrapy genspider -t crawl read www.dushu.com/book/1188_1.html

我们发现,read.py内容和我们之前不太一样了:
在这里插入图片描述

3、定义item

class ReadbookItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    name = scrapy.Field()
    src = scrapy.Field()

4、提取数据

在这里插入图片描述

read.py:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from readbook.items import ReadbookItem

class ReadSpider(CrawlSpider):
    name = "read"
    allowed_domains = ["www.dushu.com"]
    # 注意,第一个url也要匹配规则!不然会跳过第一页
    start_urls = ["https://www.dushu.com/book/1188_1.html"]

    # 规则
    rules = (Rule(LinkExtractor(allow=r"/book/1188_\d+.html"), callback="parse_item", follow=True),)

    # 解析
    def parse_item(self, response):
        img_list = response.xpath('//div[@class="bookslist"]//img')

        for img in img_list:
            name = img.xpath('./@data-original').extract_first()
            src = img.xpath('./@alt').extract_first()

            book = ReadbookItem(name=name,src=src)
            yield book

5、定义pipeline

# settings.py
ITEM_PIPELINES = {
   "readbook.pipelines.ReadbookPipeline": 300,
}
# pipelines.py
from itemadapter import ItemAdapter

class ReadbookPipeline:
    def open_spider(self,spider):
        self.fp = open('book.json','w',encoding='utf-8')

    def process_item(self, item, spider):
        self.fp.write(str(item))
        return item

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

6、启动

 scrapy crawl read

执行完毕之后,查看book.json文件。

7、保存至mysql

安装pymysql:

# 进入到python安装目录的Scripts目录
d:
cd D:\python\Scripts
# 安装 可以使用国内源
pip install pymysql

添加一个pipeline:

# settings.py
ITEM_PIPELINES = {
   "readbook.pipelines.ReadbookPipeline": 300,
   # MysqlPipeline
   'readbook.pipelines.MysqlPipeline':301
}
# 参数中一个端口号 一个是字符集 都要注意
DB_HOST = '192.168.1.1'
# 端口号是一个整数
DB_PORT = 3306
DB_USER = 'root'
DB_PASSWROD = '123'
DB_NAME = 'spider01'
# utf-8的杠不允许写
DB_CHARSET = 'utf8'

pipelines.py:

# 加载settings文件
from scrapy.utils.project import get_project_settings
import pymysql


class MysqlPipeline:

    def open_spider(self,spider):
        settings = get_project_settings()
        self.host = settings['DB_HOST']
        self.port =settings['DB_PORT']
        self.user =settings['DB_USER']
        self.password =settings['DB_PASSWROD']
        self.name =settings['DB_NAME']
        self.charset =settings['DB_CHARSET']

        self.connect()

    def connect(self):
        self.conn = pymysql.connect(
                            host=self.host,
                            port=self.port,
                            user=self.user,
                            password=self.password,
                            db=self.name,
                            charset=self.charset
        )

        self.cursor = self.conn.cursor()


    def process_item(self, item, spider):

        sql = 'insert into book(name,src) values("{}","{}")'.format(item['name'],item['src'])
        # 执行sql语句
        self.cursor.execute(sql)
        # 提交
        self.conn.commit()
        return item

    def close_spider(self,spider):
        self.cursor.close()
        self.conn.close()

七、实战:发送post请求

关键代码:

import scrapy

import json

class TestpostSpider(scrapy.Spider):
    name = 'testpost'
    allowed_domains = ['https://fanyi.baidu.com/sug']
    # post请求 如果没有参数 那么这个请求将没有任何意义
    # 所以start_urls 也没有用了
    # parse方法也没有用了
    # start_urls = ['https://fanyi.baidu.com/sug/']
    #
    # def parse(self, response):
    #     pass



	# start_requests是一个固定方法
    def start_requests(self):
        url = 'https://fanyi.baidu.com/sug'

        data = {
            'kw': 'final'
        }

        yield scrapy.FormRequest(url=url,formdata=data,callback=self.parse_second)

    def parse_second(self,response):

        content = response.text
        obj = json.loads(content,encoding='utf-8')

        print(obj)

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

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

相关文章

css自学框架之平滑滚动

今天添加的功能是平滑滚动到指定位置&#xff0c;就是单击页面的按钮&#xff0c;平滑滚动页面到对应的元素&#xff0c;可添加偏移值。 示例&#xff1a;单击ID为gundongBTN 元素&#xff0c;页面平滑滚动到其指定的ID为#topdiv对应内容&#xff0c;同时保留 5px 的偏移间距。…

Java计算机毕业设计 基于SSM+Vue医药进出口交易系统的设计与实现 Java课程设计 实战项目

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

八、实时时钟

八、实时时钟 简介时钟芯片模块代码可调时钟 简介 引脚定义和应用电路 我们的开发板没有备用电池 寄存器定义 时序定义 在时钟的上升沿&#xff0c;IO口的数据被写入到芯片中&#xff0c;在下降沿&#xff0c;芯片就会将数据输出。如果是写入&#xff0c;那么在整个过程中&…

MySQL查询表结构方法

MySQL查询数据库单个表结构代码 – 查询数据库表信息 SELECT​ COLUMN_NAME 列名,​ DATA_TYPE 字段类型,​ CHARACTER_MAXIMUM_LENGTH 长度,​ IS_NULLABLE 是否为空,​ IF(column_key PRI,Y,) 是否为主键,​ COLUMN_DEFAULT 默认值,​ COLUMN_COMMENT 备注FROM​ INFORMAT…

c++ reference_wrapper源码注释

并给出图片&#xff0c;这样就不用下载了 谢谢

实现安全的服务通信:探索如何使用服务网格来确保服务间的安全通信

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

C++,基础函数、string、引用型变量reference

9月18日 C标准库。 一、C入门基础 1、基础 入口函数与C语言相同 后缀名使用cpp 注释与c语言相同 导入c标准库无需后缀 自定义头文件与c语言相同 using namespace std; std&#xff1a;名称空间&#xff08;全局区&#xff09; cout、endl属性名称空间“std” C输出没有格式…

linux入门到精通-第三章-vi(vim)编辑器

目录 文本编辑器gedit介绍vi(vim)命令模式命令模式编辑模式末行模式 帮助教程保存文件切换到编辑模式光标移动(命令模式下)复制粘贴删除撤销恢复保存退出查找替换可视模式替换模式分屏其他用法配置文件 文本编辑器 gedit介绍 gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器…

SpringCLoud——Docker的基本介绍

什么是Docker 项目部署问题 大型项目组件较多&#xff0c;运行环境也较为复杂&#xff0c;部署时会碰到一些问题&#xff1a; 依赖关系复杂&#xff0c;容易出现兼容性问题开发、测试、生产环境有差异。 Docker Docker如何解决依赖的兼容问题的&#xff1f; 将应用的LIbs&…

GDPU 数据结构 天码行空2

实验内容 用顺序表实现病历信息的管理与查询功能。具体要求如下: 利用教材中定义顺序表类型存储病人病历信息(病历号,姓名&#xff0c;症状)&#xff1b;要求使用头文件。 设计顺序表定位查找算法&#xff0c;写成一个函数&#xff0c;完成的功能为:在线性表L中查找数据元素x…

CSS 链接:Link

文章目录 CSS 链接链接样式常见的链接样式文本修饰背景颜色案例1&#xff0c;添加不同样式的超链接2&#xff0c;高级 - 创建链接框 CSS 链接 CSS可以用来设置链接的样式&#xff0c;包括未访问的链接&#xff08;a:link&#xff09;、已访问的链接&#xff08;a:visited&…

【Linux 应用】 kworker 进程

1.简介 “kworker” 是 Linux 内核的工作线程&#xff0c;用于异步处理工作队列中的任务。这些任务包括处理硬件中断、文件系统事件、管理系统内存等。你可能会看到多个 kworker 进程&#xff0c;每个进程的名称后面都有一个数字&#xff0c;如 “kworker/0:1”、“kworker/1:…

GIF动画如何生成?简单几步快速生成gif

gif动画图片制作的方法有哪些&#xff1f;gif动图就是由一帧一帧的静态图像合成的动态效果。gif动图能够在日常聊天中缓解尴尬的气氛&#xff0c;表达你的内心想法等等。那么&#xff0c;gif动图如何自制呢&#xff1f;通过使用专业的gif动画制作&#xff08;https://www.gif.c…

Tomcat7+ Weak Password Backend Getshell Vulnerability

漏洞描述 Tomcat 支持通过后端部署 war 文件&#xff0c;所以我们可以直接将 webshell 放入 Web 目录下。为了访问后端&#xff0c;需要权限。 Tomcat7 的权限如下&#xff1a; 经理&#xff08;后台管理&#xff09; 管理器-GUI&#xff08;HTML 页面的权限&#xff09;管理…

JMeter压力测试初体验:线程组、取样器、监听器的简单使用以及如何查看压测结果

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;CSDN实力新星&#xff0c;后端开发两年经验&#xff0c;曾担任甲方技术代表&#xff0c;业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…

王国纪元 - 龙火战场+国战+IP联动ACW

IGG出品 龙火战场 类似于一个演习战场&#xff0c;给平时不常打仗的小伙伴一个打仗的机会。 大致流程&#xff1a;进场5分钟可以和朋友聊天打屁&#xff0c;商量战术&#xff0c;之后5分钟可以进攻哨塔和传送阵&#xff08;低级联赛没有传送阵&#xff09;&#xff0c;哨塔没什…

如何写出一个成熟的线上线下结合的营销方案?

分享一下咱们案例库里策划的一个线上线下结合的活动的案例。 这个活动是为了推广一个新品牌&#xff0c;增加品牌知名度和用户粘性。 你可以根据以下几个要点来进行活动策划&#xff1a; 1、目标&#xff1a; 让目标用户了解并喜欢新品牌&#xff0c;激发用户参与和分享&am…

使用延迟队列解决分布式事务问题——以订单未支付过期,解锁库存为例

目录 一、前言 二、库存 三、订单 一、前言 上一篇使用springcloud-seata解决分布式事务问题-2PC模式我们说到了使用springcloud-seata解决分布式的缺点——不适用于高并发场景 因此我们使用延迟队列来解决分布式事务问题&#xff0c;即使用柔性事务-可靠消息-最终一致性方…

【JAVASE】图书管理系统

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;浅谈Java &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 图书管理系统 1. 设计思路图2. 创建 boo…

2023年 国赛 数学建模C 基于遗传算法和神经网络的销量定价模型

一、写在开头 阅读者可能需要先阅读2023年国赛C题才能读懂下面的内容。 文章着重于解题方向指引和经历分享&#xff0c;只解释部分核心代码。 二、内容概述 刚刚做完比赛&#xff0c;对这段经历和对问题的处理方法进行下记录。 三、个人经历 今年大三&#xff0c;第一…