2024 高级爬虫笔记(六)scrapy框架基础知识

目录

  • 一、Scrapy框架基础知识
    • 1.1、什么是scrapy?
    • 1.2、scrapy的工作流程
    • 1.3、scrapy中每个模块的作用:
    • 1.4、scrapy的入门使用
      • 1.4.1 安装scrapy
      • 1.4.2、scrapy项目实现流程
      • 1.4.3、创建scrapy项目
      • 1.4.4、创建爬虫
      • 1.4.5、完善spider
      • 1.4.6、配置settings文件
      • 1.4.7、数据存储
        • 1.4.7.1、使用终端命令行进行存储
        • 1.4.7.2、利用管道pipeline来处理(保存)数据(写入文件中)
      • 1.4.8、运行scrapy
  • 二、Scrapy的进阶知识-存储
    • 2.1、了解scrapy的debug信息
    • 2.2、了解scrapyShell
    • 2.3、settings.py中的设置信息
    • 2.4、pipeline管道的深入使用
      • 2.4.1 创建工程(省略),创建爬虫,配置爬虫代码如下:
      • 2.4.2、 开启管道存储数据
        • 2.4.2.1、前期准备
        • 2.4.2.2、存储方式一——文件存储
        • 2.4.2.3、存储方式二——存储到MySQL数据库中
        • 2.4.2.4、存储方式三——存储到MongoDB数据库中
        • 2.4.2.5、存储方式四——数据同时存储到文件、MySQL、MongoDB中
      • 2.4.3 pipeline使用注意点
  • 三、Scrapy的存储实战案例
    • 3.1、需求
    • 3.2、创建工程
    • 3.3、配置settings.py
    • 3.4、爬虫实现
    • 3.5、配置数据传输格式items.py
    • 3.6、管道代码

一、Scrapy框架基础知识

1.1、什么是scrapy?

Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架,我们只需要实现少量的代码,就能够快速的抓取。

Scrapy 使用了Twisted异步网络框架,可以加快我们的下载速度。

1.2、scrapy的工作流程

1. 调度器把requests-->引擎-->下载中间件--->下载器
2. 下载器发送请求,获取响应---->下载中间件---->引擎--->爬虫中间件--->爬虫
3. 爬虫提取url地址,组装成request对象---->爬虫中间件--->引擎--->调度器
4. 爬虫提取数据--->引擎--->管道
5. 管道进行数据的处理和保存

1.3、scrapy中每个模块的作用:

   引擎(engine):负责数据和信号在不同模块间的传递 
   调度器(scheduler):实现一个队列,存放引擎发过来的request请求对象
   下载器(downloader):发送引擎发过来的request请求,获取响应,并将响应交给引擎
   爬虫(spider):处理引擎发过来的response,提取数据,提取url,并交给引擎
   管道(pipeline):处理引擎传递过来的数据,比如存储
   下载中间件(downloader middleware):可以自定义的下载扩展,比如设置代理ip
   爬虫中间件(spider middleware):可以自定义request请求和进行response过滤

1.4、scrapy的入门使用

1.4.1 安装scrapy

安装scrapy命令:
    pip install scrapy==2.5.1
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scrapy==2.5.1
    pip install scrapy-redis==0.7.2

如果安装失败. 请先升级一下pip.  然后重新安装scrapy即可.
最终你的控制台输入`scrapy version`能显示版本号. 就算成功了

1.4.2、scrapy项目实现流程

1. 创建一个scrapy项目:scrapy startproject mySpider
2. 生成一个爬虫:scrapy genspider myspider [www.xxx.cn](www.xxx.cn)
3. 提取数据:完善spider,使用xpath等方法
4. 保存数据:pipeline中保存数据

1.4.3、创建scrapy项目

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

生成的目录和文件结果如下:
在这里插入图片描述

1.4.4、创建爬虫

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

示例:

  • scrapy startproject duanzi01
  • cd duanzi01/
  • scrapy genspider duanzi duanzixing.com

生成的目录和文件结果如下:
在这里插入图片描述

1.4.5、完善spider

完善spider即通过方法进行数据的提取等操作
在/duanzi01/duanzi01/spiders/duanzi.py中修改内容如下:

import scrapy
# 自定义spider类,继承scrapy.spider
class DuanziSpider(scrapy.Spider):
     # 爬虫名字
     name = 'duanzi'
     # 允许爬取的范围,防止爬虫爬到别的网站
     allowed_domains = ['duanzixing.com']
     # 开始爬取的url地址
     start_urls = ['http://duanzixing.com/']
     # 数据提取的方法,接受下载中间件传过来的response 是重写父类中的parse方法
     def parse(self, response, **kwargs):
         # 打印抓取到的页面源码
         # print(response.text)

         # xpath匹配每条段子的article列表
         article_list = response.xpath('//article[@class="excerpt"]')
         # print(article_list)

         # 循环获取每一个article
         for article in article_list:
             # 匹配标题
             # title = article.xpath('./header/h2/a/text()')[0].extract()
             # 等同于
             title = article.xpath('./header/h2/a/text()').extract_first()
             # 获取段子内容
             con = article.xpath('./p[@class="note"]/text()').extract_first()
             print('title', title)
             print('con', con)

启动爬虫命令: scrapy crawl  duanzi

response响应对象的常用属性
- response.url:当前响应的url地址
- response.request.url:当前响应对应的请求的url地址
- response.headers:响应头
- response.request.headers:当前响应的请求头
- response.body:响应体,也就是html代码,byte类型
- response.text  返回响应的内容 字符串
- response.status:响应状态码

注意:
1. response.xpath方法的返回结果是一个类似list的类型,其中包含的是selector对象,操作和列表一样,但是有一些额外的方法
2. extract() 返回一个包含有字符串的列表  
3. extract_first() 返回列表中的第一个字符串,列表为空没有返回None
4. spider中的parse方法必须有
5. 需要抓取的url地址必须属于allowed_domains,但是start_urls中的url地址没有这个限制
6. 启动爬虫的时候注意启动的位置,是在项目路径下启动

1.4.6、配置settings文件

- ROBOTSTXT_OBEY = False
  robots是一种反爬协议。在协议中规定了哪些身份的爬虫无法爬取的资源有哪些。
  在配置文件中setting,取消robots的监测:

- 在配置文件中配置全局的UA:USER_AGENT='xxxx'

- 在配置文件中加入日志等级:LOG_LEVEL = 'ERROR'  只输出错误信息

  其它日志级别:
  - CRITICAL  严重错误
  - ERROR  错误
  - WARNING  警告
  - INFO  消息
  - DEBUG   调试

1.4.7、数据存储

1.4.7.1、使用终端命令行进行存储
- 代码配置
  /myspider/myspider/spiders/ITSpider.py

   class ITSpider(scrapy.Spider):
       name = 'ITSpider'
       start_urls = ['https://duanzixing.com/page/2/']
   
       # 通过终端写入文件的方式
       def parse(self, response):
           article_list = response.xpath('/html/body/section/div/div/article')
           # 创建列表, 存储数据
           all_data = []
           for article in article_list:
               title = article.xpath('./header/h2/a/text()').extract_first()
               con = article.xpath('./p[2]/text()').extract_first()
               dic = {
                   'title': title,
                   'con': con
               }
               all_data.append(dic)
           return all_data

- 终端命令
  scrapy crawl ITSpider -o ITSpider.csv  
  将文件存储到ITSpider.csv  文件中
1.4.7.2、利用管道pipeline来处理(保存)数据(写入文件中)
1、打开 myspider/myspider/items.py文件,添加如下代码:
   import scrapy

   class DuanziproItem(scrapy.Item):
       title = scrapy.Field()
       con = scrapy.Field()

2、打开/myspider/myspider/spiders/ITSpider.py文件,添加如下代码:
   import scrapy
   from myspider.items import DuanziproItem
   
   class ITSpiderSpider(scrapy.Spider):
       name = 'ITSpider'
       start_urls = ['https://duanzixing.com/page/2/']
   
       # 写入管道 持久化存储
       def parse(self, response):
           article_list = response.xpath('/html/body/section/div/div/article')
           for article in article_list:
               title = article.xpath('./header/h2/a/text()').extract_first()
               con = article.xpath('./p[2]/text()').extract_first()
               item = DuanziproItem()
               item['title'] = title
               item['con'] = con
               yield item

2.1、为什么要使用yield?
  让整个函数变成一个生成器,遍历这个函数的返回值的时候,挨个把数据读到内存,不会造成内存的瞬间占用过高
  注意:yield能够传递的对象只能是:BaseItem,Request,dict,None

3、打开管道文件myspider/myspider/pipelines.py 添加如下代码:、
   class ITSpiderPipeline:
       f = None
       def open_spider(self, spider):
           print('爬虫开始时被调用一次')
           self.f = open('./duanzi.text', 'w')
           
       # 爬虫文件中提取数据的方法每yield一次item,就会运行一次
       # 该方法为固定名称函数
       def process_item(self, item, spider):
           print(item)
           self.f.write(item['title']+item['con']+'\n')
           return item
   
       def close_spider(self, spider):
           print('爬虫结束时被调用')
           self.f.close()

3.1、open_spider方法
    重写父类中open_spider方法,只有爬虫开始时被调用一次

3.2、close_spider 方法
    重写父类中lose_spider方法  爬虫结束时被调用一次

4、在settings.py设置开启pipeline
  将默认被注释的管道打开
   ITEM_PIPELINES = {
      'myspider.pipelines.MyspiderPipeline': 300,
   }
  其中数值代表优先级,数值越小优先级越高

1.4.8、运行scrapy

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

二、Scrapy的进阶知识-存储

2.1、了解scrapy的debug信息

在这里插入图片描述

2.2、了解scrapyShell

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

使用方法:
scrapy shell http://www.baidu.com

在终端输入上述命令后,能够进入python的交互式终端,此时可以使用:
- response.xpath():直接测试xpath规则是否正确
- response.url:当前响应的url地址
- response.request.url:当前响应对应的请求的url地址
- response.headers:响应头
- response.body:响应体,也就是html代码,默认是byte类型
- response.request.headers:当前响应的请求头

2.3、settings.py中的设置信息

1、USER_AGENT 设置ua

2、ROBOTSTXT_OBEY 是否遵守robots协议,默认是遵守

3、CONCURRENT_REQUESTS 设置并发请求的数量,默认是164、DOWNLOAD_DELAY 下载延迟,默认无延迟 (下载器在从同一网站下载连续页面之前应等待的时间(以秒为单位)。这可以用来限制爬行速度,以避免对服务器造成太大影响)

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

6、DEFAULT_REQUEST_HEADERS 设置默认请求头,这里加入了USER_AGENT将不起作用

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

8、DOWNLOADER_MIDDLEWARES 下载中间件

9、LOG_LEVEL 控制终端输出信息的log级别,终端默认显示的是debug级别的log信息
  - LOG_LEVEL = "WARNING"
    - CRITICAL  严重
    - ERROR  错误
    - WARNING  警告
    - INFO  消息
    - DEBUG   调试

10、LOG_FILE 设置log日志文件的保存路径,如果设置该参数,终端将不再显示信息
  LOG_FILE = "./test.log"

2.4、pipeline管道的深入使用

2.4.1 创建工程(省略),创建爬虫,配置爬虫代码如下:

1、打开items.py文件,添加如下代码:

注意:属性名称和当前爬虫db.py中抓到要存储数据的变量一致,否则报错
class DoubanfileItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    img_src = scrapy.Field()
    name = scrapy.Field()
    to_star = scrapy.Field()

2、打开db.py文件,添加如下代码:
import scrapy
import re
from doubanfile.items import DoubanfileItem

class DbSpider(scrapy.Spider):
    name = 'db'
    allowed_domains = ['https://movie.douban.com/chart']
    start_urls = ['https://movie.douban.com/chart']

    def parse(self, resp, **kwargs):
        item = DoubanfileItem()  # 实例化item类
        # print(resp.text)
        # 先获取到每一行数据的tr
        tr_list = resp.xpath('//div[@class="indent"]/div/table/tr[@class="item"]')
        for tr in tr_list:
            # 获取封面
            item['img_src'] = tr.xpath('./td[1]/a/img/@src').extract_first()
            # 电影名称
            name = tr.xpath('./td[2]/div[@class="pl2"]/a//text()').extract_first()
            # 去除空白字符使用replace替换
            # name = name.replace('\n', '').replace('\r', '').replace('/', '').replace(' ', '')
            # 去除空白字符使用正则替换
            item['name'] = re.sub('(/)|(\s)', '', name)
            # 主演
            item['to_star'] = tr.xpath('./td[2]/div[@class="pl2"]/p[@class="pl"]/text()').extract_first()
            yield item

2.4.2、 开启管道存储数据

2.4.2.1、前期准备
pipeline中常用的方法:
1. process_item(self,item,spider):实现对item数据的处理
2. open_spider(self, spider): 在爬虫开启的时候仅执行一次
3. close_spider(self, spider): 在爬虫关闭的时候仅执行一次

settings.py 打开当前注释:
ITEM_PIPELINES = {
   'doubanfile.pipelines.DoubanfilePipeline': 300,
}
2.4.2.2、存储方式一——文件存储
打开pipelines.py文件,添加如下代码:

class DoubanfilePipeline:
    f = None
    def open_spider(self, item):
        self.f = open('./db.text', 'w')

    def process_item(self, item, spider):
        print(item)
        self.f.write(item['img_src']+'\n')
        self.f.write(item['name']+'\n')
        self.f.write(item['to_star']+'\n')
        return item

    def close_spider(self, item):
        self.f.close()

注意:当前process_item中的return item必须存在,如果当前爬虫存在于多个管道的时候,如果没有return item 则下一个管道不能获取到当前的item数据
2.4.2.3、存储方式二——存储到MySQL数据库中
1、创建数据库表
create database douban character set utf8;
use douban
CREATE TABLE `douban` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `img_src` varchar(200) NOT NULL COMMENT '封面地址',
  `name` varchar(50) NOT NULL COMMENT '电影名称',
  `to_star` varchar(250) NOT NULL COMMENT '主演',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

2、打开pipelines.py文件,添加如下代码:

from itemadapter import ItemAdapter
import pymysql

class DoubanmysqlPipeline:
    db = None
    cursor = None
    def open_spider(self, spider):
        # 判断当前运行的是否为db爬虫,不是db爬虫则下面代码不执行
        # 当前仅限于一个scrapy下有多个爬虫工程
        if spider.name == 'db':
            self.db = pymysql.connect(host='127.0.0.1', port=3306, db='douban', user='root', passwd='123456', charset='utf8')
            self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        # 判断当前运行的是否为db爬虫
        if spider.name == 'db':
            try:
                sql = f'insert into douban(img_src, name, to_star) values("{item["img_src"]}", "{item["name"]}", "{item["to_star"]}")'
                self.cursor.execute(sql)
                self.db.commit()
            except Exception as e:
                print(e)
                print(sql)
                self.db.rollback()
                return item

    def close_spider(self, item):
        # 关闭数据库连接
        self.db.close()
2.4.2.4、存储方式三——存储到MongoDB数据库中
打开pipelines.py文件,添加如下代码:

from itemadapter import ItemAdapter
from pymongo import MongoClient

class DoubanmongodbPipeline:
    con = None
    collection = None
    def open_spider(self, spider):  # 在爬虫开启的时候仅执行一次
        if spider.name == 'db':
            self.con = MongoClient(host='127.0.0.1', port=27017) # 实例化mongoclient
            self.collection = self.con.spider.douban  # 创建数据库名为spider,集合名为douban的集合操作对象

    def process_item(self, item, spider):
        if spider.name == 'db':
            # print(spider.name)
            self.collection.insert_one(dict(item)) # 此时item对象需要先转换为字典,再插入
        # 不return的情况下,另一个权重较低的pipeline将不会获得item
        return item

    def close_spider(self, item):
        # 关闭数据库连接
        self.con.close()

注意:
需要开启mongo服务
mongod.exe  --dbpath=C:/User/xxx/db

新开终端
mongo.exe
2.4.2.5、存储方式四——数据同时存储到文件、MySQL、MongoDB中
1、打开pipelines.py文件,添加如下代码:

from itemadapter import ItemAdapter
import pymysql
from pymongo import MongoClient

class DoubanFilePipeline:
    '''
    设置文件存储
    '''
    f = None
    def open_spider(self, item):
        self.f = open('./db.text', 'w')

    def process_item(self, item, spider):
        print(item)
        self.f.write(item['img_src'] + '\n')
        self.f.write(item['name'] + '\n')
        self.f.write(item['to_star'] + '\n')
        return item

    def close_spider(self, item):
        self.f.close()

class DoubanmysqlPipeline:
    '''
    存储到MySQL数据库中
    '''
    db = None
    cursor = None
    def open_spider(self, spider):
        # 判断当前运行的是否为db爬虫,不是db爬虫则下面代码不执行
        # 当前仅限于一个scrapy下有多个爬虫工程
        if spider.name == 'db':
            self.db = pymysql.connect(host='127.0.0.1', port=3306, db='douban', user='root', passwd='123456', charset='utf8')
            self.cursor = self.db.cursor()

    def process_item(self, item, spider):
        # 判断当前运行的是否为db爬虫
        if spider.name == 'db':
            try:
                sql = f'insert into douban(img_src, name, to_star) values("{item["img_src"]}", "{item["name"]}", "{item["to_star"]}")'
                self.cursor.execute(sql)
                self.db.commit()
            except Exception as e:
                print(e)
                print(sql)
                self.db.rollback()
        return item
    
    def close_spider(self, item):
        # 关闭数据库连接
        self.db.close()

class DoubanmongodbPipeline:
    '''
    存储到MongoDB数据库中
    '''
    con = None
    collection = None
    def open_spider(self, spider):  # 在爬虫开启的时候仅执行一次
        if spider.name == 'db':
            self.con = MongoClient(host='127.0.0.1', port=27017) # 实例化mongoclient
            self.collection = self.con.spider.douban  # 创建数据库名为spider,集合名为douban的集合操作对象

    def process_item(self, item, spider):
        if spider.name == 'db':
            # print(spider.name)
            self.collection.insert_one(dict(item)) # 此时item对象需要先转换为字典,再插入
        # 不return的情况下,另一个权重较低的pipeline将不会获得item
        return item

    def close_spider(self, item):
        # 关闭数据库连接
        self.con.close()

2、修改settings.py 添加管道
ITEM_PIPELINES = {
   'douban.pipelines.DoubanFilePipeline': 300,  # 300表示权重
   'douban.pipelines.DoubanmysqlPipeline': 400,
   'douban.pipelines.DoubanmongodbPipeline': 500,
}

注意:在此设置中分配给类的整数值决定了它们运行的顺序:项目从低值到高值的类。通常将这些数字定义在 0-1000 范围内。

思考:pipeline在settings中能够开启多个,为什么需要开启多个?
1. 不同的pipeline可以处理不同爬虫的数据,通过spider.name属性来区分
2. 不同的pipeline能够对一个或多个爬虫进行不同的数据处理的操作,比如一个进行数据清洗,一个进行数据的保存
3. 同一个管道类也可以处理不同爬虫的数据,通过spider.name属性来区分

2.4.3 pipeline使用注意点

1. 使用之前需要在settings中开启
2. pipeline在setting中键表示位置(即pipeline在项目中的位置可以自定义),值表示距离引擎的远近,越近数据会越先经过
3. 有多个pipeline的时候,process_item的方法必须return item,否则后一个pipeline取到的数据为None4. pipeline中process_item的方法必须有,否则item没有办法接受和处理
5. process_item方法接受item和spider,其中spider表示当前传递item过来的spider
6. open_spider(spider) :能够在爬虫开启的时候执行一次
7. close_spider(spider) :能够在爬虫关闭的时候执行一次
8. 上述俩个方法经常用于爬虫和数据库的交互,在爬虫开启的时候建立和数据库的连接,在爬虫关闭的时候断开和数据库的连接

三、Scrapy的存储实战案例

3.1、需求

抓取网站:https://movie.douban.com/chart 中子页面的数据
实现思路:
    + 先对第一层url进行请求
    + 请求返回数据进行解析循环  找到每一条子页面的url
    + 找到子页面的url以后进行再次请求
    + 请求解析子页面请求返回的数据
    + 结束

3.2、创建工程

+ scrapy startproject doubandetail
+ cd doubandetail
+ scrapy genspider db movie.douban.com/chart

3.3、配置settings.py

# 设置日志级别
LOG_LEVEL = 'ERROR'
ROBOTSTXT_OBEY = False
COOKIES_ENABLED = False  # cookies的中间件将不起作用,下面的cookie起作用

# 设置请求头
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 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36',
  'Cookie': '设定cookie 防止反扒'
}

# 开启管道
ITEM_PIPELINES = {
   'doubandetail.pipelines.DoubandetailPipeline': 300,
}

3.4、爬虫实现

+ 打开db.py,添加如下代码:

  import scrapy
  from doubandetail.items import DoubandetailItem
  import re

  class DbSpider(scrapy.Spider):
      name = 'db'
      start_urls = ['http://movie.douban.com/chart/']

      def parse(self, resp, **kwargs):
          print(resp.text)
          # 先获取到每一行数据的tr
          tr_list = resp.xpath('//div[@class="indent"]/div/table/tr[@class="item"]')
          for tr in tr_list:
              # 获取每个详情页的url
              detail_url = tr.xpath('./td[1]/a/@href').extract_first()
              # 请求子页面
              print(detail_url)
              yield scrapy.Request(detail_url, callback=self.parse_deatil)

      # 解析子页面数据
      def parse_deatil(self, response):
          # 默认携带我们settings.py中所配置的请求头进行请求
          # print(response.request.headers)
          item = DoubandetailItem()
          item['name'] = response.xpath('//*[@id="content"]/h1/span[1]/text()').extract_first()  # 电影名称
          item['director'] = response.xpath('//*[@id="info"]/span[1]/span[2]/a/text()').extract_first()  # 导演
          item['screenwriter'] = ''.join(response.xpath('//*[@id="info"]/span[2]/span[2]//text()').extract())  # 编剧
          item['to_star'] = ''.join(response.xpath('//*[@id="info"]/span[3]/span[2]//text()').extract())  # 主演
          item['type'] = '/'.join(response.xpath('//span[@property="v:genre"]//text()').extract())  # 类型
          item['link_report'] = re.sub('(/)|(\s)|(\u3000)|(\'\n\')', '', link_report)
          print(item)
          return item

+ 注意:
  需要将allowed_domains注释掉,否则详情页url不符合当前允许,所以会出现不请求的问题

3.5、配置数据传输格式items.py

import scrapy

class DoubandetailItem(scrapy.Item):
    name = scrapy.Field()  # 电影名称
    director = scrapy.Field()  # 导演
    screenwriter = scrapy.Field()  # 编剧
    to_star = scrapy.Field()  # 主演
    type = scrapy.Field()  # 类型

3.6、管道代码

from itemadapter import ItemAdapter
from pymongo import MongoClient

class DoubandetailPipeline:
    con = None
    collection = None
    def open_spider(self, spider):  # 在爬虫开启的时候仅执行一次
        self.con = MongoClient(host='127.0.0.1', port=27017)  # 实例化mongoclient
        self.collection = self.con.spider.douban  # 创建数据库名为spider,集合名为douban的集合操作对象

    def process_item(self, item, spider):
        print(item)
        self.collection.insert_one(dict(item))  # 此时item对象需要先转换为字典,再插入
        return item

    def close_spider(self, item):
        # 关闭数据库连接
        self.con.close()

注意:
如果访问频率过高被禁止访问,可以携带登录后的cookie进行访问

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

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

相关文章

每日一题-两个链表的第一个公共结点

文章目录 两个链表的第一个公共结点问题描述示例说明示例 1示例 2 方法及实现方法描述代码实现 复杂度分析示例运行过程示例 1示例 2 总结备注 两个链表的第一个公共结点 问题描述 给定两个无环的单向链表&#xff0c;找到它们的第一个公共节点。如果没有公共节点&#xff0c…

Elasticsearch:在 HNSW 中提前终止以实现更快的近似 KNN 搜索

作者&#xff1a;来自 Elastic Tommaso Teofili 了解如何使用智能提前终止策略让 HNSW 加快 KNN 搜索速度。 在高维空间中高效地找到最近邻的挑战是向量搜索中最重要的挑战之一&#xff0c;特别是当数据集规模增长时。正如我们之前的博客文章中所讨论的&#xff0c;当数据集规模…

两种方式实现Kepware与PLC之间的心跳检测

两种方式实现Kepware与PLC之间的心跳检测 实现Kepware与PLC之间的心跳检测1.OPCUA 外挂程序2.Kepware Advanced Tag 实现Kepware与PLC之间的心跳检测 1.OPCUA 外挂程序 这是通过上位程序来触发心跳的一种机制&#xff0c;在C#中&#xff0c;可以利用OPC UAOPCAutodll的方式…

python-leetcode-文本左右对齐

68. 文本左右对齐 - 力扣&#xff08;LeetCode&#xff09; class Solution:def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:result []current_line []current_length 0for word in words:# 如果当前行加上这个单词后超过 maxWidth&#xff0c;则…

全新免押租赁系统打造便捷安全的租赁体验

内容概要 全新免押租赁系统的推出&#xff0c;标志着租赁行业的一次重大变革。这个系统的最大特点就是“免押金”&#xff0c;大大减轻了用户在租赁过程中的经济负担。从此&#xff0c;不再需要为一部手机或其他商品支付高昂的押金&#xff0c;用户只需通过简单的信用评估&…

WordPress静态缓存插件WP Super Cache与 WP Fastest Cache

引言 WordPress是一款开源的内容管理系统&#xff08;CMS&#xff09;&#xff0c;最初作为博客平台开发&#xff0c;现已发展成为一个功能强大的建站工具&#xff0c;支持创建各种类型的网站&#xff0c;包括企业网站、在线商店、个人博客等。它具有用户友好的界面、丰富的插…

1.CSS的复合选择器

1.1 什么是复合选择器 在CSS中&#xff0c;可以根据选择器的类型把选择器分为基础选择器和复合选择器&#xff0c;复合选择器是建立在基础选择器之上&#xff0c;对基础选择器进行组合形成的。 复合选择器可以更精准、更高效的选择目标元素&#xff08;标签&#xff09; 复…

初学stm32 --- ADC模拟/数字转换器工作原理

目录 常见的ADC类型 并联比较型工作示意图 逐次逼近型工作示意图 ADC的特性参数 STM32各系列ADC的主要特性 ADC框图简介 参考电压/模拟部分电压 输入通道&#xff08; F1为例&#xff09; 转换序列&#xff08;F1为例&#xff09; 规则组和注入组执行优先级对比 规则…

【C++】深入理解迭代器(Iterator)

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;什么是迭代器&#xff1f;迭代器与指针的比较 &#x1f4af;std::string 中的迭代器示例代码与图示分析运行结果&#xff1a;图示说明&#xff1a; 小提示 &#x1f4af;正…

H266/VVC 帧内预测中 MDIS 技术

参考像素平滑滤波 MDIS VVC 的帧内预测参考像素获取过程和 HEVC 相同&#xff0c;但参考像素滤波过程有所改进。在H.266中 MDIS&#xff08;Mode Dependent Intra Smoothing&#xff09;即模式依赖帧内平滑滤波&#xff0c;是对帧内预测的亮度分量参考像素进行滤波决策的一个技…

Chrome访问https页面显示ERR_CERT_INVALID,且无法跳过继续访问

在访问网页的时候&#xff0c;因为浏览器自身的安全设置问题&#xff0c; 对于https的网页访问会出现安全隐私的提示&#xff0c; 甚至无法访问对应的网站&#xff0c;尤其是chrome浏览器&#xff0c; 因此本文主要讲解如何设置chrome浏览器的设置&#xff0c;来解决该问题&…

深入解析 Transformer:从原理到可视化再到PyTorch实现

文章目录 深入解析 Transformer1 理解 Transformer1.1 理解自注意力机制 (Self-Attention)1.2 理解位置编码 (Positional Encoding)1.2.1 整数编码1.2.2 正弦编码 1.3 理解编码器和解码器模块1.3.1 编码器 1.4 最终线性层和 Softmax 层 2 编写 Transformer 的代码2.1 摘要和引言…

系统架构设计师考点—软件工程基础知识

一、备考指南 软件工程基础知识主要考查的是软件工程基础、软件开发方法、系统分析、设计、测试及运行和维护等相关知识&#xff0c;同时也是重点考点&#xff0c;在系统架构设计师的考试中选择题12~15分&#xff0c;案例分析和论文中也会考到相关内容&#xff0c;属于重点章节…

电影动画shader解析与实现

着色器代码解析 大家好&#xff01;我是 [数擎AI]&#xff0c;一位热爱探索新技术的前端开发者&#xff0c;在这里分享前端和Web3D、AI技术的干货与实战经验。如果你对技术有热情&#xff0c;欢迎关注我的文章&#xff0c;我们一起成长、进步&#xff01; 开发领域&#xff1a;…

使用ML.NET进行对象检测

1、前言 ML.NET 是面向 .NET 开发人员的开源跨平台机器学习框架&#xff0c;支持将自定义机器学习模型集成到 .NET 应用程序中。 它包含一个 API&#xff0c;其中包含不同的 NuGet 包、名为 模型生成器的 Visual Studio 扩展&#xff0c;以及作为 .NET 工具安装的 命令行接口。…

年会抽奖Html

在这里插入图片描述 <!-- <video id"backgroundMusic" src"file:///D:/background.mp3" loop autoplay></video> --> <divstyle"width: 290px; height: 580px; margin-left: 20px; margin-top: 20px; background: url(D:/nianhu…

vue -关于浏览器localstorge数据定期清除的实现

1.实现背景 用户登录时的信息存在了localstorge中&#xff0c;但它会一直存在。一般来说&#xff0c;我们希望这个数据能够定期被清除掉&#xff0c;以下一个定时清除的实现。 2.实现原理 在用户登录时&#xff0c;将用户信息存入localstorge的同时&#xff0c;将当前时间作…

LabVIEW水轮发电机组振动摆度故障诊断

本文介绍了基于LabVIEW的水轮发电机组振动摆度故障诊断系统的设计与实施过程。系统在通过高效的故障诊断功能&#xff0c;实现水轮发电机组的振动、温度等关键指标的实时监控与智能分析&#xff0c;从而提高电力设备的可靠性和安全性。 ​ 项目背景 随着电力行业对设备稳定性…

Collaborate with AI -- Write a modern C++ singleton factory

translate my blog <<与AI合作 -- 写一个modern c单例工厂>> to English. NOTE: It was written at 2024.01, maybe the AI is not smart as now. Preface In this article, readers can learn about a hybrid of the modern C singleton pattern and factory pat…

【轻松学C:编程小白的大冒险】--- C语言简介 02

在编程的艺术世界里&#xff0c;代码和灵感需要寻找到最佳的交融点&#xff0c;才能打造出令人为之惊叹的作品。而在这座秋知叶i博客的殿堂里&#xff0c;我们将共同追寻这种完美结合&#xff0c;为未来的世界留下属于我们的独特印记。 【轻松学C&#xff1a;编程小白的大冒险】…