下一代自动化爬虫神器--playwright,所见即所得,配合逆向不要太香!!!

news2024/11/18 4:20:23

文章目录

  • 1.Playwright介绍
  • 2.与 Selenium 和 pyppeteer 相比,Playwright 具有以下几个区别和优势
  • 3.在爬虫中使用 Playwright 的好处
  • 4.环境安装
  • 5.屏幕录制
  • 6.保留记录cookie信息
  • 7.playwright代码编写详解
    • 1.第一个Playwright脚本
      • (1)同步模式
      • (2)异步模式
    • 2.元素定位(重点)
      • (1)CSS选择器定位
    • 3.设置内容输入的时间间隔
    • 4.更多操作
    • 5.xpath定位
    • 6.Context上下文(重点)
    • 7.实战案例

1.Playwright介绍

Playwright 是一个用于自动化浏览器操作的开源工具,由 Microsoft 开发和维护。
它支持多种浏览器(包括 Chromium、Firefox 和 WebKit)和多种编程语言(如 Python、JavaScript 和 C#),可以用于测试、爬虫、自动化任务等场景。

Playwright 是针对 Python 语言的纯自动化工具,它可以通过单个API自动执行 Chromium,Firefox 和 WebKit 浏览器,连代码都不用写,就能实现自动化功能,并同时支持以无头模式、有头模式运行。

2.与 Selenium 和 pyppeteer 相比,Playwright 具有以下几个区别和优势

  1. 多浏览器支持:支持所有主流浏览器。这使得开发人员可以根据需求选择最适合的浏览器进行自动化操作。(Playwright不支持旧版Microsoft Edge或IE11)
  2. 更快的执行速度:Playwright 通过使用浏览器的底层调试协议来进行操作,相比于 Selenium 和 pyppeteer,playwright是异步的,它具有更快的执行速度和更低的资源消耗。
  3. 可靠性和稳定性:Playwright 提供了更可靠和稳定的浏览器自动化操作,通过使用浏览器的原生 API 来模拟用户行为,避免了一些传统自动化工具的一些限制和不稳定性。
  4. 支持跨浏览器和跨平台:Playwright 可以在不同浏览器和不同操作系统上运行,这使得开发人员可以更方便地进行跨浏览器和跨平台的测试和自动化操作。
  5. selenium是基于http协议,而Playwright是基于websocket协议。由于使用 HTTP 协议,Selenium 的性能相对较低。每次与浏览器进行通信时,都需要发送 HTTP 请求和等待响应。
    而Playwright使用 WebSocket 协议,Playwright 的性能会更高。WebSocket 的双向通信使得数据交换更高效,可以更快地获取页面内容和执行操作。
  6. 支持屏幕录制功能:根据屏幕录制指定生成相关操作代码。

3.在爬虫中使用 Playwright 的好处

  1. 动态网页爬取:Playwright 可以模拟用户在浏览器中的操作,包括渲染 JavaScript、点击按钮、填写表单等,从而可以爬取包含动态内容的网页。
  2. 多浏览器支持:Playwright 支持多种浏览器,可以根据需求选择最适合的浏览器进行爬取,以确保爬取结果的准确性和一致性。
  3. 更高的稳定性和可靠性:Playwright 使用浏览器的原生 API 进行操作,避免了一些传统爬虫工具的一些限制和不稳定性,提供了更可靠和稳定的爬取能力。

总之,Playwright 是一个功能强大、跨浏览器、跨平台的浏览器自动化工具,相比于 Selenium 和 pyppeteer,它具有更快的执行速度、更高的稳定性和更广泛的浏览器支持,适用于多种自动化操作和爬虫场景。

4.环境安装

  • 系统要求:

    • Python 3.8 或更高版本。
    • Windows 10+、Windows Server 2016+ 或适用于 Linux 的 Windows 子系统 (WSL)。
    • MacOS 12 Monterey 或 MacOS 13 Ventura。
    • Debian 11、Debian 12、Ubuntu 20.04 或 Ubuntu 22.04。
  • 安装playwright的python版本

    • pip install playwright
  • 安装Playwright所需的所有工具插件和所支持的浏览器

    • playwright install
    • 该步骤耗时较长

安装playwright的python版本
在这里插入图片描述

安装Playwright所需的所有工具插件和所支持的浏览器
在这里插入图片描述

5.屏幕录制

  • 创建一个py文件,比如:main.py

  • 在终端中,执行如下指令:

  • playwright codegen -o main.py

    • 将屏幕录制生成的代码保存到main.py文件中
    • 可以通过如下设置,生成同步还是异步的代码:

在终端执行这个命令,会根据我们在浏览器的操作,生成相应的代码
在这里插入图片描述

默认生成的代码时同步的,我们可以在target这里修改,Library Async,改为异步
在这里插入图片描述

点击停止录制,就会在本地生成我们操作浏览器的代码
在这里插入图片描述

查看生成的爬虫代码
在这里插入图片描述

我们可以在本地run测试一下
在这里插入图片描述

可以看到,程序就会按我们之前操作的步骤运行,全程不用自己手动写代码!!!
在这里插入图片描述

  • playwright codegen --viewport-size=800,600 www.baidu.com -o main.py

    • 访问指定网址,并且设置浏览器窗口大小

playwright codegen --device=“iPhone 13” -o main.py

  • 模拟手机设备进行网络请求(只支持手机模拟器,无需单独安装)
  • 支持的移动端设备如下:目前对安卓设备的覆盖率不高
"Blackberry PlayBook",  "Blackberry PlayBook landscape",  "BlackBerry Z30",  "BlackBerry Z30 landscape",  "Galaxy Note 3",  "Galaxy Note 3 landscape",  "Galaxy Note II",  "Galaxy Note II landscape",  "Galaxy S III",  "Galaxy S III landscape",  "Galaxy S5",  "Galaxy S5 landscape",  "Galaxy S8",  "Galaxy S8 landscape",  "Galaxy S9+",  "Galaxy S9+ landscape",  "Galaxy Tab S4",  "Galaxy Tab S4 landscape",  "iPad (gen 5)",  "iPad (gen 5) landscape",  "iPad (gen 6)",  "iPad (gen 6) landscape",  "iPad (gen 7)",  "iPad (gen 7) landscape",  "iPad Mini",  "iPad Mini landscape",  "iPad Pro 11",  "iPad Pro 11 landscape",  "iPhone 6",  "iPhone 6 landscape",  "iPhone 6 Plus",  "iPhone 6 Plus landscape",  "iPhone 7",  "iPhone 7 landscape",  "iPhone 7 Plus",  "iPhone 7 Plus landscape",  "iPhone 8",  "iPhone 8 landscape",  "iPhone 8 Plus",  "iPhone 8 Plus landscape",  "iPhone SE",  "iPhone SE landscape",  "iPhone X",  "iPhone X landscape",  "iPhone XR",  "iPhone XR landscape",  "iPhone 11",  "iPhone 11 landscape",  "iPhone 11 Pro",  "iPhone 11 Pro landscape",  "iPhone 11 Pro Max",  "iPhone 11 Pro Max landscape",  "iPhone 12",  "iPhone 12 landscape",  "iPhone 12 Pro",  "iPhone 12 Pro landscape",  "iPhone 12 Pro Max",  "iPhone 12 Pro Max landscape",  "iPhone 12 Mini",  "iPhone 12 Mini landscape",  "iPhone 13",  "iPhone 13 landscape",  "iPhone 13 Pro",  "iPhone 13 Pro landscape",  "iPhone 13 Pro Max",  "iPhone 13 Pro Max landscape",  "iPhone 13 Mini",  "iPhone 13 Mini landscape",  "iPhone 14",  "iPhone 14 landscape",  "iPhone 14 Plus",  "iPhone 14 Plus landscape",  "iPhone 14 Pro",  "iPhone 14 Pro landscape",  "iPhone 14 Pro Max",  "iPhone 14 Pro Max landscape",  "Kindle Fire HDX",  "Kindle Fire HDX landscape",  "LG Optimus L70",  "LG Optimus L70 landscape",  "Microsoft Lumia 550",  "Microsoft Lumia 550 landscape",  "Microsoft Lumia 950",  "Microsoft Lumia 950 landscape",  "Nexus 10",  "Nexus 10 landscape",  "Nexus 4",  "Nexus 4 landscape",  "Nexus 5",  "Nexus 5 landscape",  "Nexus 5X",  "Nexus 5X landscape",  "Nexus 6",  "Nexus 6 landscape",  "Nexus 6P",  "Nexus 6P landscape",  "Nexus 7",  "Nexus 7 landscape",  "Nokia Lumia 520",  "Nokia Lumia 520 landscape",  "Nokia N9",  "Nokia N9 landscape",  "Pixel 2",  "Pixel 2 landscape",  "Pixel 2 XL",  "Pixel 2 XL landscape",  "Pixel 3",  "Pixel 3 landscape",  "Pixel 4",  "Pixel 4 landscape",  "Pixel 4a (5G)",  "Pixel 4a (5G) landscape",  "Pixel 5",  "Pixel 5 landscape",  "Pixel 7",  "Pixel 7 landscape",  "Moto G4",  "Moto G4 landscape"

6.保留记录cookie信息

录制过程中,如果用到了cookie,playwright会自动将cookie信息保存到指定文件中,文件一定要是json类型文件

  • playwright codegen --save-storage=auth.json https://www.17k.com
    • 在屏幕录制时,进行登录操作,登录后,cookie信息会被保存到auth.json文件中
      在终端执行
      在这里插入图片描述

手动登录一次
在这里插入图片描述

关掉页面
在本地生成一个json文件
在这里插入图片描述

我们可以再次录制,基于之前生成的json文件,这次程序就可以自动登录了

  • playwright codegen --load-storage=auth.json https://www.17k.com -o main.py
    • 基于auth.json进行屏幕录制,会自动进入到登录成功后的页面中

可以看到账号的书架了
在这里插入图片描述

7.playwright代码编写详解

playwright我们用with语句启动,可以避免:
1、忘记关闭文件
2、语句有异常,未做处理

在看下之前用start和stop的启动方式

from playwright.sync_api import sync_playwright # 先导包
playwright = sync_playwright().start() # 创建playwright对象
browser = playwright.chromium.launch(headless=False) # 启动谷歌浏览器赋值给对象
page = browser.new_page() # 打开一个页面
page.goto(‘https://www.baidu.com/’) # 打开百度地址
browser.close() # 关闭浏览器对象
playwright.stop() # 关闭playwright对象释放资源

1.第一个Playwright脚本

(1)同步模式

from playwright.sync_api import sync_playwright  #导入同步模块

#创建一个Playwright的管理器对象
with sync_playwright() as p: # p = sync_playwright()
    #基于p创建一个浏览器对象(默认就是谷歌浏览器对象)
    bro = p.chromium.launch(headless=False)
    #创建一个浏览器页面
    page = bro.new_page()
    #在指定的页面中进行请求发送
    page.goto('https://www.baidu.com')
    #暂定2s中
    page.wait_for_timeout(2000)
    #获取访问页面的标题
    title = page.title()
    #获取页面的页面源码数据(重要=》可见即可得)
    page_text = page.content()
    print(page_text,title)

    page.close()
    bro.close()

在这里插入图片描述

在这里插入图片描述

(2)异步模式

import asyncio
from playwright.async_api import async_playwright
#封装一个特殊的函数
async def main():
    async with async_playwright() as p:  # p = sync_playwright()
        # 基于p创建一个浏览器对象(谷歌浏览器对象)
        bro = await p.chromium.launch(headless=False)
        # 创建一个浏览器页面
        page = await bro.new_page()
        # 在指定的页面中进行请求发送
        await page.goto('https://www.baidu.com')
        # 暂定2s中
        await page.wait_for_timeout(2000)
        # 获取访问页面的标题
        title = await page.title()
        # 获取页面的页面源码数据(重要=》可见即可得)
        page_text = await page.content()
        print(page_text, title)

        await page.close()
        await bro.close()

asyncio.run(main())

我们写的更多的是同步代码

2.元素定位(重点)

比较常用的有两种,css选择器和xpath选择器

(1)CSS选择器定位

  • 语法结构:page.locator()
    • 参数:标签/id/层级/class 选择器
  • 交互操作:
    • 点击元素, click() 方法
    • 元素内输入文本, fill() 方法

我们先看下浏览器中的标签
在这里插入图片描述

代码:

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    bro = p.chromium.launch(headless=False,slow_mo=2000)   #slow_mo放慢执行速度,从而可以容易跟踪操作,单位是毫秒。是全局的每步操作的等待时间
    page = bro.new_page()
    page.goto('https://www.baidu.com')

    
    #定位到输入框,进行文本录入
    page.locator('#kw').fill('Python教程')    #id定位
    # 定位搜索按钮,进行点击操作
    page.locator('#su').click()
    #go_back() 后退操作,go_forward() 是页面前进
    page.go_back()

    
    page.locator('.s_ipt').fill('爬虫')  # class定位 class里面如果有空格的话,空格切分的都是class的属性值,选择器选择的拿其中一个就行,但是这个class必须唯一才能选到
    page.locator('#su').click()
    page.go_back()

    
    page.locator('input#kw').fill('人工智能')    # 标签+属性定位
    page.locator('#su').click()
    page.go_back()

    
    page.locator('#form > span > input#kw').fill('数据分析')  #层级定位
    page.locator('#su').click()

    page.close()
    bro.close()

针对class选择器,如果某个class属性有多个标签使用的话,可以使用标签+属性值一起定位
在这里插入图片描述

3.设置内容输入的时间间隔

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    bro = p.chromium.launch(headless=False)
    page = bro.new_page()
    page.goto('https://www.baidu.com')

    #方式1:
    #input_tag = page.locator('#kw').press_sequentially('hello world',delay=500)
    
    #方式2:设置内容的输入的时间间隔
    tag = page.locator('#kw') #id定位
    tag.focus() #聚焦于当前标签
    input_text = 'Hello, World!'
    for char in input_text:
        page.keyboard.type(char, delay=500)

    # 定位搜索按钮,进行点击操作
    page.locator('#su').click()

    page.close()
    bro.close()

模拟人的操作,一个一个字符输入
在这里插入图片描述

4.更多操作

  • locator.all() #获取所有标签

  • locator.count() #获取标签个数

  • locator.nth(index) #根据标签索引获取某个标签

  • inner_text() #获取标签内的所有文本内容

  • get_by_text(xxx) #根据标签的文本内容做标签定位

  • get_attribute(attrName) #获取标签属性值

  • taobao在不登录情况下无法进行商品搜索,因此需要手动登录,保留Cookie信息

    • playwright codegen --save-storage=taobao.json https://www.taobao.com
  • 携带Cookie信息进行操作:

    • context = browser.new_context(storage_state=“taobao.json”)

代码:

from playwright.sync_api import Playwright, sync_playwright, expect

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False,slow_mo=2000)
    context = browser.new_context(storage_state="taobao.json")
    #创建页面时,通过context来创建,此时创建的页面就携带了我们的cookie
    page = context.new_page()
    page.goto("https://www.taobao.com/")

    page.locator('#q').fill('mac pro')
    # class属性值为btn-search tb-bg,在定位的时候选择空格左右两侧任意一个属性值即可,但是一定要确认是唯一的
    page.locator('.btn-search').click()
    page.wait_for_timeout(1000)

    # 根据文本定位
    page.get_by_text('发货地').click()
    page.wait_for_timeout(1000)

    # 定位到满足要求所有的标签(商品列表最外层的a标签)
    locator = page.locator('.Content--contentInner--QVTcU0M > div > a')
    all_eles = locator.all()  #将标签保存到列表中

    # 查看定位到满足要求标签的数量
    count = locator.count()
        print(count)
    # 定位到第10个a标签,nth下标从0开始
    a_10 = locator.nth(9)
    #get_attribute('href')得到href属性值,inner_text()是文本内容,所有文本内容

    print(a_10.get_attribute('href'), a_10.inner_text())
    print('---------------------------------------------------------------------------')
    # 获得每一个a标签中的文本内容和href属性值
    for index in range(count):
        ele = locator.nth(index) #得到第几个标签
        text = ele.inner_text()
        href = ele.get_attribute('href')
        print(text, href)

    page.close()
    context.close()
    browser.close()

5.xpath定位

page.locator(xpath表达式)

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    bro = p.chromium.launch(headless=False,slow_mo=2000)
    page = bro.new_page()
    page.goto('https://www.bilibili.com/')

    #xpath定位
    page.locator('//*[@id="nav-searchform"]/div[1]/input').fill('Python教程')
    page.locator('//*[@id="nav-searchform"]/div[2]').click()

    page.wait_for_timeout(4000)
    page.close()
    bro.close()

在这里插入图片描述

6.Context上下文(重点)

浏览器的上下文管理对象Context可以用于管理Context打开/创建的多个page页面。
并且可以创建多个Context对象,那么不同的Context对象打开/创建的page之间是相互隔离的(每个Context上下文都有自己的Cookie、浏览器存储和浏览历史记录)。

  • 打开百度的多个链接对应的page页面
    在这里插入图片描述

看下标签
在这里插入图片描述

from playwright.sync_api import sync_playwright

# 点击百度首页中左上角的全部链接,以打开多个不同的page页面
with sync_playwright() as p:
    bro = p.chromium.launch(headless=False, slow_mo=1000)
    # 创建上下文管理对象
    context = bro.new_context()
    # 基于上下文管理对象打开一个page页面
    page = context.new_page()
    page.goto('https://www.baidu.com')
    # 点击百度首页中左上角的全部链接,以打开多个不同的page页面
    a_list = page.locator('//*[@id="s-top-left"]/a').all()
    for a in a_list:
        a.click()
    # 使用上下文管理对象获取浏览器打开的所有page页面
    pages = context.pages
    for sub_page in pages:
        # 遍历每一个page,打印起page标题
        print(sub_page.title())

    page.wait_for_timeout(3000)
    page.close()
    bro.close()

在这里插入图片描述

可以看到可以打印出每个page的title
在这里插入图片描述

通过sub_page的title判断进行sub_page页面的切换和管理

from playwright.sync_api import sync_playwright


# 封装页面切换的函数
def switch_to_page(context, title):
    for page in context.pages:
        if title == page.title():
            # 浏览器停留在此page页面
            page.bring_to_front()
            return page


# 点击百度首页中左上角的全部链接,以打开多个不同的page页面
with sync_playwright() as p:
    bro = p.chromium.launch(headless=False, slow_mo=1000)
    # 创建上下文管理对象
    context = bro.new_context()
    # 基于上下文管理对象打开一个page页面
    page = context.new_page()
    page.goto('https://www.baidu.com')
    # 点击百度首页中左上角的全部链接,以打开多个不同的page页面
    a_list = page.locator('//*[@id="s-top-left"]/a').all()
    for a in a_list:
        a.click()

    # page页面的切换,switch_to_page是自己封装的函数
    select_page = switch_to_page(context, 'hao123_上网从这里开始')
    # 在指定的page中进行相关操作
    select_page.locator('//*[@id="search"]/form/div[2]/input').fill('测试测试')
    select_page.locator('//*[@id="search"]/form/div[3]/input').click()

    page.close()
    bro.close()

页面切换到hao123,并输入指定内容点击查询
在这里插入图片描述

7.实战案例

  • 抓取bili中指定关键字搜索页面中视频的标题和作者名称
from playwright.sync_api import sync_playwright
from lxml import etree
#封装页面切换的函数,可以根据标题,也可以根据url等切换
def switch_to_page(context,title):
    for page in context.pages:
        if title == page.title():
            #浏览器停留在此page页面
            page.bring_to_front()
            return page
with sync_playwright() as p:
    bro = p.chromium.launch(headless=False,slow_mo=1000)
    context = bro.new_context()
    page = context.new_page()
    page.goto('https://www.bilibili.com/')

    #xpath定位
    page.locator('//*[@id="nav-searchform"]/div[1]/input').fill('Python教程')
    page.locator('//*[@id="nav-searchform"]/div[2]').click()

    #切换到新打开的page中,我们封装的函数返回的就是需要的页面
    select_page = switch_to_page(context,'Python教程-哔哩哔哩_Bilibili')
    page_text = select_page.content()
    tree = etree.HTML(page_text)
    div_list = tree.xpath('//*[@id="i_cecream"]/div/div[2]/div[2]/div/div/div/div[3]/div/div')
    for div in div_list:
        title = div.xpath('.//h3[@class="bili-video-card__info--tit"]/@title')[0]
        author = div.xpath('.//span[@class="bili-video-card__info--author"]/text()')[0]
        print(title,author)

    page.wait_for_timeout(3000)
    page.close()
    bro.close()

在这里插入图片描述

得到查出来的视频课程名称和作者
在这里插入图片描述

不同用户登录,加载不同cookie就可以使用context,不用用户使用不同context。没必要使用多个浏览器
当爬虫逆向比较困难时,可以结合playwright来爬取数据
逆向中,playwright可以很好做浏览器环境补充
这些playwright进阶用法,我们下次接着讲,感兴趣的朋友请一键三连,谢谢!

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

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

相关文章

小米标准模组+MCU 快速上手开发(二)——之模组串口调试

小米标准模组MCU 开发笔记之固件调试 背景技术名词简介● 小米IoT开发者平台● 小米IoT 模组● 固件● OTA● CRC32 固件双串口调试● MHCWB6S-IB 模组资料下载● MHCWB6S-IB 模组管脚图● 上电调试 背景 小米标准模组MCU的开发过程中,由于部分官方资料较为古早&am…

解决MobaXterm网络错误连接超时问题

报错页面: 报错原因: ①网络断开了 ②网络端口,端口号改变 解决办法: ①重新连接网络按R ②固定端口号 第一步:编辑------>虚拟机网络编辑器(我的Linux在虚拟机里) 第二步:用…

【触想智能】工业平板知识分享|选购工业平板电脑需要注意的7大事项

工业平板电脑是一种将显示器、工控主板、触摸屏和其他电子设备整合在一起的电子产品。它广泛应用于工业控制和自动化领域。 在购买工业平板电脑时,需要考虑一些关键性因素,以确保工业平板电脑是安全可靠、运行稳定的。那么我们在购买工业平板电脑的时候&…

js设计模式:计算属性模式

作用: 将对象中的某些值与其他值进行关联,根据其他值来计算该值的结果 vue中的计算属性就是很经典的例子 示例: let nowDate 2023const wjtInfo {brithDate:1995,get age(){return nowDate-this.brithDate}}console.log(wjtInfo.age,wjt年龄)nowDate 1console.log(wjtInf…

5 原型模式 Prototype

1.模式定义: 指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 2.应用场景: 当代码不应该依赖于需要复制的对象的具体类时,请使用Prototype模式。 Spring源码中的应用 org.springframework.beans.factory.support.AbstractB…

飞天使-k8s知识点24-kubernetes实操9-数据存储2配置存储

文章目录 高级存储pvc生命周期 配置存储secret 高级存储 前面已经学习了使用NFS提供存储,此时就要求用户会搭建NFS系统,并且会在yaml配置nfs。由于kubernetes支持的存储系统有很多,要求客户全都掌握,显然不现实。为了能够屏蔽底层…

排序算法1:冒泡排序、快速排序、插入排序

排序算法&#xff1a;交换类排序&#xff0c;插入类排序、选择类排序、归并类排序 交换类排序&#xff1a;冒泡排序、快速排序 一、冒泡排序 #include <stdio.h> #include <stdlib.h> #include <time.h> typedef int ElemType; typedef struct{ElemType *e…

C++面试宝典第31题:有效的数独

题目 判断一个9 x 9的数独是否有效。只需要根据以下规则,验证已经填入的数字是否有效即可。 1、数字1-9在每一行只能出现一次。 2、数字1-9在每一列只能出现一次。 3、数字1-9在每一个以粗实线分隔的3 x 3宫内只能出现一次。 下图是一个部分填充的有效的数独,数独部分空格内已…

Django学习笔记-HTML实现MySQL的图片上传

1.django项目编写index.html代码 创建form表单,路由指向upload,请求方式post,enctype设置"multipart/form-data", post请求添加{% csrf_token %},编写两个input,上传和提交 2.添加upload路由 3.views中创建upload 1).获取上传的文件,没有上传则返回"没有指定…

面试答疑03

1、登录鉴权怎么做的&#xff1f;为什么采用jwt的方式&#xff1f;有什么好处&#xff1f; Java登录鉴权常见的实现方式包括**CookieSession、HTTP Basic Authentication、ServletJDBC**等。 在Java的Web应用中&#xff0c;登录鉴权是确认用户身份的关键环节。一个常用的传统…

线性代数:向量空间

目录 向量空间 Ax 0 的解空间S Ax b 的全体解向量所构成集合不是向量空间 基、维数、子空间 自然基与坐标 例1 例2 向量空间 Ax 0 的解空间S Ax b 的全体解向量所构成集合不是向量空间 基、维数、子空间 自然基与坐标 例1 例2

计算机设计大赛 深度学习卫星遥感图像检测与识别 -opencv python 目标检测

文章目录 0 前言1 课题背景2 实现效果3 Yolov5算法4 数据处理和训练5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **深度学习卫星遥感图像检测与识别 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐…

Ps:灰度模式

Ps菜单&#xff1a;图像/模式/灰度 Image/Mode/Grayscale 灰度 Grayscale模式是一种特定的色彩模式&#xff0c;用于处理没有彩色信息的图像。 在灰度模式下&#xff0c;图像不包含颜色&#xff0c;只显示黑色、白色及其间的灰色阶。 这种模式对于需要强调光影、纹理和形状而不…

速卖通跨境智星批量注册账号所需要的资源介绍

在寻找批量注册速卖通买家账号的道路上&#xff0c;我们发现了一个强大的工具——速卖通跨境智星。但在使用它之前&#xff0c;我们需要准备以下关键资源&#xff1a; 邮箱&#xff1a;注册买家号必不可少的资源之一。我们推荐使用国外的邮箱服务&#xff0c;比如outlook、Hot…

不破不立,那些年错过的Python

随着OpenAI的发展&#xff0c;Python的重要性不言而喻。不知你是否和我一样&#xff0c;不知道曾经说过多少次我要学Python&#xff0c;都没有执行起来… 近期我在知识库中更新了一波Python教程&#xff0c;选取了这一篇分享给大家。 前言 很多时候我们需要让程序变成交互性的…

【LeetCode】升级打怪之路 Day 01:二分法

今日题目&#xff1a; 704. 二分查找35. 搜索插入位置34. 在排序数组中查找元素的第一个和最后一个位置 目录 今日总结Problem 1: 二分法LeetCode 704. 二分查找 【easy】LeetCode 35. 搜索插入位置 ⭐⭐⭐⭐⭐LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置 【medi…

类和对象 01【C++】

目录 一、 类的引入1. 类的定义2. 类的访问限定符及封装(1) 访问限定符(2) 封装 3. 类的实例化4. 类对象模型(1) 计算类对象的大小(2) 类对象的存储方式 5. this指针 二、 类的6个默认成员函数1. 构造函数2. 析构函数3. 拷贝构造函数4. 赋值运算符重载5. 取地址重载6. const取地…

gem5学习(23):经典缓存——Classic Caches

目录 一、Interconnects 1、Crossbars 二、Debugging 官网教程&#xff1a;gem5: Classic caches 默认缓存是一个带有MSHR&#xff08;未命中状态保持寄存器&#xff09;和WB&#xff08;写缓冲区&#xff09;的非阻塞缓存&#xff0c;用于读取和写入未命中。缓存还可以启用…

常用驱动适配总结

I2C驱动 I2C中主要包含5个管脚&#xff0c;包括&#xff1a;复位信号&#xff0c;中断信号&#xff0c;I2C时钟信号&#xff0c;I2C数据信号&#xff0c;触摸屏供电信号&#xff08;我的电路供电没有控制信号&#xff09;。设备树相对简单了很多。 SCL和SDA管脚是需要在i2c的…

WebRTC最新版报错解决:city.wav:missing and no known rule to make it (二十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…