selenium用法

news2024/11/22 22:02:37

一、请求库selenium

selenium是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题。操作浏览器模拟人的行为。

下载浏览器驱动:以谷歌浏览器为例---->谷歌浏览器驱动(版本号对应)

安装:pip3 install selenium

基本使用(元素定位和操作)

from selenium import webdriver
import time

# 浏览器对象,打开了谷歌浏览器
bro=webdriver.Chrome(executable_path='./chromedriver.exe')

# 在浏览器中输入一个网站并访问
bro.get('http://www.baidu.com')

# 通过id找到input输入框,往输入框中输入美女,敲回车
kw=bro.find_element_by_id('kw')
kw.clear() # 清空
kw.send_keys('美女')  # 输入
search=bro.find_element_by_css_selector('#su')
search.click() # 点击该控件

print(bro.page_source) # 加载完js后的页面内容

time.sleep(3)
bro.close()  # 关闭页面
bro.quit()  # 关闭整个浏览器

无界面浏览器

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()

chrome_options.add_argument('window-size=1920x3000') # 指定浏览器分辨率
chrome_options.add_argument('--disable-gpu') # 谷歌文档提到需要加上这个属性来规避bug
chrome_options.add_argument('--hide-scrollbars') # 隐藏滚动条, 应对一些特殊页面
chrome_options.add_argument('blink-settings=imagesEnabled=false') # 不加载图片, 提升速度
chrome_options.add_argument('--headless') # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败

bro=webdriver.Chrome(executable_path='./chromedriver.exe',options=chrome_options)

# 在浏览器中输入一个网站并访问
bro.get('https://www.baidu.com')

print(bro.page_source) # 页面内容,加载完js后

bro.close()

获取元素位置、属性、大小

from selenium import webdriver
import base64

bro = webdriver.Chrome(executable_path='./chromedriver.exe')

bro.get('https://kyfw.12306.cn/otn/resources/login.html')
driver.implicitly_wait(10)

user_login=driver.find_element_by_css_selector('.login-hd-account>a')
user_login.click()
time.sleep(2)

img = bro.find_element_by_id('J-qrImg')

print(img.id)    # selenium提供的id,忽略
print(img.tag_name) # 标签名

print('-----')  # 后续根据位置和大小把图截出来,一般是验证码,破解,自动输入
print(img.location) # img标签的位置
print(img.size)     # img标签大小

# 获取属性
src=img.get_attribute('src')
res=base64.b64decode(src.split(',')[-1])
with open('扫描.png','wb') as f:
    f.write(res)

隐式、显式等待
显式等待:指定某个标签等待时间,写起来复杂用的少

wait=WebDriverWait(driver,10)
wait.until(EC.presence_of_element_located((By.ID,'content_left')))
contents=browser.find_element(By.CSS_SELECTOR,'#content_left')

隐式等待:只要代码中要去找某一个标签,如果没有加载出来,就会等待设置的固定时间(秒)

# 只需要写一句话,等待所有要获取的标签
driver.implicitly_wait(10)
driver.find_element_by_css_selector()

示例:

from selenium import webdriver
import time

bro=webdriver.Chrome(executable_path='./chromedriver.exe')

# 隐式等待,等所有---->只要代码中要去找某一个标签,如果没有加载出来,就会等待10s
# 再找控件,只要没加载成功,就会等待,最多等10s
bro.implicitly_wait(10)

# 显式等待,指定某个标签等待,写起来复杂用的少
bro.get('http://www.baidu.com')

# 找到页面中登录按钮
# login_btn=bro.find_element_by_css_selector('#s-top-loginbtn')  #  css 选择器
# login_btn=bro.find_element_by_xpath('//*[@id="s-top-loginbtn"]')  #  xpath 选择器

# 自带的
# login_btn=bro.find_element_by_id('s-top-loginbtn')  #  selenium自带的选择器
login_btn=bro.find_element_by_link_text('登录')  #  selenium自带的选择器,通过a标签内容
# login_btn=bro.find_element_by_partial_link_text('录') # selenium自带的选择器,通过a标签内容模糊

# login_btn=bro.find_elements_by_class_name() # selenium自带的选择器,通过类名
# login_btn=bro.find_elements_by_name() # selenium自带的选择器,通过name属性
# login_btn=bro.find_elements_by_tag_name() # selenium自带的选择器,通过标签名

# 点击登录按钮
login_btn.click()

# 找到用户名框
name=bro.find_element_by_id('TANGRAM__PSP_11__userName')
password=bro.find_element_by_id('TANGRAM__PSP_11__password')
name.send_keys('xxx@qq.com')
password.send_keys('xxx')

submit=bro.find_element_by_id('TANGRAM__PSP_11__submit')
# 找到密码框
time.sleep(3)

submit.click()

time.sleep(3)

bro.close()

执行js

from selenium import webdriver
import time

bro=webdriver.Chrome(executable_path='./chromedriver.exe')
bro.implicitly_wait(10)

bro.get('http://www.baidu.com')

# bro.execute_script('console.log(vm)')
# bro.execute_script('alert(1)')
bro.execute_script('alert(document.cookie)')  # 这里面写js代码

time.sleep(3)
bro.close()

切换选项卡

import time
from selenium import webdriver

browser=webdriver.Chrome(executable_path='./chromedriver.exe')
browser.get('https://www.baidu.com')

browser.execute_script('window.open()')  # 执行js代码,查找一个已经存在的或新建的浏览器窗口

print(browser.window_handles) # 获取所有的选项卡

# 选择选项卡
# browser.switch_to_window(browser.window_handles[1])
browser.switch_to.window(browser.window_handles[1])
browser.get('https://www.taobao.com')
time.sleep(3)

browser.switch_to_window(browser.window_handles[0])
browser.get('https://www.sina.com.cn')

browser.close()
browser.quit()  # 关闭整个浏览器

模拟前进后退

import time
from selenium import webdriver

browser = webdriver.Chrome(executable_path='./chromedriver.exe')

browser.get('https://www.baidu.com')
browser.get('https://www.taobao.com')
browser.get('http://www.sina.com.cn/')

# 后退
browser.back()
time.sleep(2)
# 前进
browser.forward()
browser.close()

异常处理

from selenium import webdriver
from selenium.common.exceptions import TimeoutException, NoSuchElementException, NoSuchFrameException

browser = webdriver.Chrome()
try:
    browser.get('http://www.baidu.com')
except Exception as e:
    print(e)
finally:
    browser.close()

动作链
在这里插入图片描述

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素
import time
from selenium.webdriver import ActionChains

driver = webdriver.Chrome()
driver.get('http://www.runoob.com/try/try.php?filename=jqueryui-api-droppable')
wait=WebDriverWait(driver,3)
try:
    driver.switch_to.frame('iframeResult') # 切换到iframeResult
    sourse=driver.find_element_by_id('draggable')
    target=driver.find_element_by_id('droppable')

    actions=ActionChains(driver) # 拿到动作链对象
    actions.drag_and_drop(sourse,target) # 把动作放到动作链中,准备串行执行
    actions.perform()  # 释放鼠标让动作生效
    time.sleep(2)
finally:
    driver.close()

示例:
12306的滑动

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait  # 等待页面加载某些元素
import time
from selenium.webdriver import ActionChains

from selenium.webdriver.chrome.options import Options

# 防止前端检测出我们是通过自动化软件控制的
options = Options()
options.add_argument("--disable-blink-features=AutomationControlled")
driver = webdriver.Chrome(executable_path='./chromedriver.exe', chrome_options=options)

# driver = webdriver.Chrome()
driver.get('https://kyfw.12306.cn/otn/resources/login.html')

wait = WebDriverWait(driver, 3)

try:
    username_login = driver.find_element_by_link_text('账号登录')
    username_login.click()

    username = driver.find_element_by_id('J-userName')
    password = driver.find_element_by_id('J-password')
    username.send_keys('xxxxxxxxxxx')
    password.send_keys('xxx')
    time.sleep(2)
    submit = driver.find_element_by_id('J-login')
    submit.click()
    time.sleep(5)

    hk = driver.find_element_by_id('nc_1_n1z')

    actions = ActionChains(driver)  # 拿到动作链对象
    actions.drag_and_drop_by_offset(hk, 300, 0)
    actions.perform()
    time.sleep(50)
finally:
    driver.close()

在这里插入图片描述
注:
滑块验证,前端会判断是机器还是人工操作(window.navigator.webdriver==true),防止检测出我们是通过自动化软件控制的,需配置options.add_argument("--disable-blink-features=AutomationControlled")

selenium登录cnblogs获取cookie
为了登录到某个网站,拿到cookie,使用selenium速度慢,使用requests发送请求。
半自动登录到cnblogs,拿到cookie,保存到本地;下次,在打开页面把cookie写入浏览器就是登录状态。

import time
from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10)

###########  登录过程  ###########
# try:
#     driver.get('https://www.cnblogs.com/')
#
#     # 找到登录,点击
#     login = driver.find_element_by_css_selector('#navbar_login_status > a:nth-child(6)')
#     login.click()
#     username = driver.find_element_by_id('mat-input-0')
#     password = driver.find_element_by_id('mat-input-1')
#     username.send_keys('xxx@qq.com')
#     password.send_keys('xxx')
#
#     input('手动输入用户名密码')
#
#     summit = driver.find_element_by_css_selector(
#         'body > app-root > mat-sidenav-container > mat-sidenav-content > div > div > app-sign-in > app-content-container > div > div > div > form > div > button')
#     summit.click()
#
#     # 验证码(自动破解、手动破解)
#     input('已经破解了验证码,敲回车')
#
#     # 获取cookie
#     print(type(driver.get_cookies()))
#
#     # 把cookie保存到文件中
#     import json
#
#     with open('cnblogs.json', 'w', encoding='utf-8') as f:
#         f.write(json.dumps(driver.get_cookies()))
#
#     time.sleep(5)
#
# except Exception as e:
#     print(e)
#
# finally:
#     driver.close()


# 不登录,使用代码把cookie写入浏览器
import json

driver.get('https://www.cnblogs.com/')
# 把cookie写入浏览器
with open('../cnblogs.json', 'r', encoding='utf-8') as f:
    cookies = json.loads(f.read())

for cookie in cookies:  # cookie的json文件是列表形式,套字典,放一个个字典,所以用循环往里放
    driver.add_cookie(cookie)

# 刷新一下页面
driver.refresh()

time.sleep(10)
driver.close()

抽屉半自动点赞
selenium登录拿到cookie,再使用requests携带cookie发送请求。

from selenium import webdriver
import json
import time

#### 登录过程 ####
# bro=webdriver.Chrome(executable_path='chromedriver.exe')
# bro.implicitly_wait(10)
# bro.get('https://dig.chouti.com/')
# try:
#     sub_btn=bro.find_element_by_id('login_btn')
#     print(sub_btn)
#
#     # sub_btn.click()  # 报错
#     bro.execute_script('arguments[0].click();',sub_btn)  # 拿到控件,通过执行js代码,让js去执行点击
#
#     # username=bro.find_element_by_css_selector('body > div.login-dialog.dialog.animated2.scaleIn > div > div.login-body > div.form-item.login-item.clearfix.phone-item.mt24 > div.input-item.input-item-short.left.clearfix > input')
#     username=bro.find_element_by_css_selector('div.input-item>input.login-phone')
#     username.send_keys('18953675221')
#     # password=bro.find_element_by_css_selector('body > div.login-dialog.dialog.animated2.scaleIn > div > div.login-footer > div.form-item.login-item.clearfix.mt24 > div')
#     password = bro.find_element_by_css_selector('div.input-item>input.pwd-password-input')
#     password.send_keys('lqz123')
#
#     time.sleep(3)
#     btn=bro.find_element_by_css_selector('body > div.login-dialog.dialog.animated2.scaleIn > div > div.login-footer > div:nth-child(4) > button')
#
#     btn.click()
#
#     input('等')
#
#     with open('chouti.json','w') as f:
#         json.dump(bro.get_cookies(),f)
#
# finally:
#     bro.close()


#### 点赞过程 ####
import requests

bro = webdriver.Chrome(executable_path='chromedriver.exe')
bro.implicitly_wait(10)
bro.get('https://dig.chouti.com/')

# 使用把屏幕滑倒最底下,如果有加载,就加载完成了
bro.execute_script('window.scrollTo(0, document.body.scrollHeight);')
# bro.find_elements_by_css_selector('.link-item')
cookie = {}

## 从文件中读出cookie
with open('../chouti.json', 'r') as f:
    res = json.load(f)

# 这是requests使用的cookie
for item in res:
    cookie[item['name']] = item['value']
print(cookie)  # requests能够使用的cookie

div = bro.find_element_by_class_name('link-con')
time.sleep(2)
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36'
}
div_list = div.find_elements_by_class_name('link-item')
for div in div_list:
    article_id = div.get_attribute('data-id')
    print(article_id)
    # 使用requests发送请求
    res = requests.post('https://dig.chouti.com/link/vote', data={'linkId': article_id}, cookies=cookie, headers=header)
    print(res.text)
bro.close()

二、打码平台使用

验证码种类

  • 简单的字母数字的---->验证码截图出来---->图像识别(OCR识别)---->数字字母
  • 12306之前的,找出符合的图片
  • 滑动验证
  • 计算类…

验证码破解

  • 人工破解
  • 自动破解
    打码平台(验证码破解平台,成功率没有100%)---->云打码、超级鹰等---->给它一张图片,识别后返回结果(收费的)

超级鹰的使用
下载源代码
输入账号密码、软件ID、验证码类型、上传图片,发送请求即可识别。

#!/usr/bin/env python
# coding:utf-8

import requests
from hashlib import md5


class Chaojiying_Client(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        password = password.encode('utf8')
        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }

    def PostPic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()

    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


if __name__ == '__main__':

    # res=requests.get('https://api.django-vue-admin.com/admin/captcha/image/1784cd5088e40cd3fb97f811ea8bd49befd646f7/')
    # with open('js.png','wb') as f:
    #     f.write(res.content)


    chaojiying = Chaojiying_Client('xxx', 'xxx', '903641')  # 账号 密码 用户中心>>>软件ID 生成一个替换 96001
    im = open('js.png', 'rb').read()
    print(chaojiying.PostPic(im, 6001))

注:账号需充值积分,才可以使用。

三、xpath使用

一门在html中查找数据的语言。

记住的语法

/   取当前路径下的xx  # 从当前标签下找 /body/a/img
//  取所有路径下的xx  # 从当前标签的子子孙孙找 //a
标签名字 # //p
.   当前路径  # ./p .//p
..  上一层  # //body//a[1]/..     
@   取属性  # //a[@href="image.html"] 

示例

doc = '''
<html>
 <head>
  <base href='http://example.com/' />
  <title href="http://example.com/">Example website</title>
 </head>
 <body>
  <div id='images'>
   <a href='image1.html' xx='yy'>Name: My image 1 <br /><img src='image1_thumb.jpg' /></a>
   <a href='image2.html'>Name: My image 2 <br /><img src='image2_thumb.jpg' /></a>
   <a href='image3.html'>Name: My image 3 <br /><img src='image3_thumb.jpg' /></a>
   <a href='image4.html' class='li'>Name: My image 4 <br /><img src='image4_thumb.jpg' /></a>
   <a href='image5.html' class='li li-item' name='items'>Name: My image 5 <br /><img src='image5_thumb.jpg' /></a>
   <a href='image6.html' name='items'><span><h5>test</h5></span>Name: My image 6 <br /><img src='image6_thumb.jpg' /></a>
  </div>
 </body>
</html>
'''

# 以lxml模块为例
from lxml import etree

html = etree.HTML(doc)  # 要解析的字符串(html)
# 如果是文件,使用贡献
# html=etree.parse('search.html',etree.HTMLParser())

# 1 所有节点
a=html.xpath('//*')
a=html.xpath('/*')

# 2 指定节点(结果为列表)
a=html.xpath('//head')  # 找出所有的head标签

# 3 子节点,子孙节点
a=html.xpath('//div/a')
a=html.xpath('//body/a') #无数据
a=html.xpath('//body//a')

# 4 父节点
a=html.xpath('//body//a[@href="image1.html"]/..')
# a=html.xpath('//body//a[1]/..')  # 第一个a标签
a=html.xpath('//a[1]')  # 第一个a标签
# 也可以这样
a=html.xpath('//body//a[1]/parent::*')

# 5 属性匹配
a=html.xpath('//body//a[@href="image1.html"]')
a=html.xpath('//a[@href="image1.html"]')

a=html.xpath('//base[@href="http://example.com/"]')
a=html.xpath('//*[@href="http://example.com/"]')

# 6 文本获取
a=html.xpath('//body//a[@href="image1.html"]/text()')
a=html.xpath('//a/text()')

# 7 属性获取
a=html.xpath('//body//a/@href')
a=html.xpath('//body//a[1]/@xx')
# # 注意从1 开始取(不是从0)
a=html.xpath('//body//a[1]/@href')

# 8 属性多值匹配
# a标签有多个class类,直接匹配就不可以了,需要用contains
a=html.xpath('//body//a[@class="li"]')

a=html.xpath('//body//a[contains(@class,"li")]')

a=html.xpath('//body//a[contains(@class,"li")]/text()')

# 9 多属性匹配
a=html.xpath('//body//a[contains(@class,"li") or @name="items"]')
a=html.xpath('//body//a[contains(@class,"li") and @name="items"]/text()')
a=html.xpath('//body//a[contains(@class,"li")]/text()')

# 10 按序选择
a=html.xpath('//a[2]/text()')
a=html.xpath('//a[2]/@href')
a=html.xpath('//a/@href[contains(@class,"vervideo-lilink")]/@href')
# 取最后一个
a=html.xpath('//a[last()]/@href')
# 位置小于3的
a=html.xpath('//a[position()<3]/@href')
# 倒数第二个
a=html.xpath('//a[last()-2]/@href')

# 11 节点轴选择
# ancestor:祖先节点
# 使用了* 获取所有祖先节点
a=html.xpath('//a/ancestor::*')
a=html.xpath('//a/ancestor::div')
# # 获取祖先节点中的div
a=html.xpath('//a/ancestor::div')
# attribute:属性值
a=html.xpath('//a[1]/attribute::*')
# child:直接子节点
a=html.xpath('//a[1]/child::*')
a=html.xpath('//a[1]/child::img')
# descendant:所有子孙节点
a=html.xpath('//a[6]/descendant::*')

# following:当前节点之后所有节点
a=html.xpath('//a[1]/following::*')
a=html.xpath('//a[1]/following::*[1]/@href')

# following-sibling:当前节点之后同级节点
a=html.xpath('//a[1]/following-sibling::*')
a=html.xpath('//a[1]/following-sibling::a')
a=html.xpath('//a[1]/following-sibling::*[2]')
a = html.xpath('//a[1]/following-sibling::*[2]/@href')

print(a)

总结
selenium:

  • 只要人能做的,都可以使用代码实现

  • 隐式,显式等待

  • 模拟前进后退

  • 切换选项卡

  • 执行js

  • 异常处理

  • 动作链:模拟点击,拖拽行为

  • 自动登录12306(前端能够检测到是否使用了selenium)

  • 获取登录的cookie
    继续使用selenium:add_cookie
    使用requests携带cookie

  • 抽屉半自动点赞

xpath语法:
lxml为例(lxml是解析器),bs4、re、selenium自带的、lxml这些都有xpath、css。

/
//
.
..
标签名
*
[@属性名='属性值']
类的话:有多个

打码平台:

  • 花点钱破解验证码
  • 原理:平台提供了接口,使用http传递图片给它,它给你破解,返回破解后的数据
  • 本质用了requests模块
  • 字母和数字:图像识别---->ocr技术
  • 复杂的:人工

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

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

相关文章

K8S应用生命周期管理

K8S应用生命周期管理. 1 应用周期管理1.1 资源对象1.1.1 基础知识1.1.2 资源属性 1.2 Pod基础1.2.1 Pod概述1.2.2 简单实践1.2.3 流程解读1.2.4 应用解析1.2.5 初始化容器1.2.6 Sidecar实践1.2.7 静态POD实践 1.3 Pod进阶1.3.1 Pod探测机制1.3.2 命令探测1.3.3 TCP探测1.3.4 HT…

C# +.Net医院检验科LIS系统源码 实验室信息系统源码

实验室信息系统&#xff08;Laboratory Information System&#xff0c;缩写LIS&#xff09;是一类用来处理实验室过程信息的软件。这套系统通常与其他信息系统比如医院信息系统&#xff08;HIS&#xff09;连接。实验室信息系统由多种实验室流程模块构成&#xff0c;这些模块可…

79-基于stm32单片机酒精浓度测量疲劳驾驶检测系统(程序+原理图+元件清单全套资料)...

资料编号&#xff1a;079 功能介绍&#xff1a;采用stm32单片机作为主控CPU&#xff0c;采用MQ3传感器采集酒精浓度&#xff0c;采用红外接触传感器感应驾驶员上车时间&#xff0c;OLED显示酒精浓度和驾驶时间&#xff0c;当酒精浓度超过阈值&#xff08;程序可调&#xff09;&…

【QT】——多线程的使用

目录 基本概念 1.线程类QThread 1.1信号和槽 1.2静态函数 1.3 任务处理函数 2.实例 第一种方式 第二种方式 基本概念 默认的线程在Qt中称之为窗口线程&#xff0c;也叫主线程&#xff0c;负责窗口事件处理或者窗口控件数据的更新子线程负责后台的业务逻辑处理&#xff…

Rocky Linux能否通过其他方法合法地获得RHEL源代码?让我们一起来看看吧

在红帽公司限制对RHEL源代码的访问后&#xff0c;Rocky Linux寻找了替代方案来确保他们可以继续获取所需的源代码并行使他们的权利。他们认为这种限制违反了开源的精神和目的&#xff0c;因此积极寻求解决方案&#xff0c;以维护他们对开源软件的承诺。那么Rocky Linux能否通过…

AOM、VTM初体验及安装tensorflow

AOM、VTM初体验 Cmake cmake的定义是什么 &#xff1f;-----高级编译配置工具 当你用不同的语言或者编译器开发一个项目&#xff0c;各就各位code完之后要生成最终的输出&#xff08;dll 或执行文件&#xff09;&#xff0c;这时候就尴尬了&#xff0c;你要手动去MingGW或者…

Kotlin 1.9 新特性预览:data object (数据单例)

前言 data object (数据单例) 是 Kotlin 1.9 中预定引入的新特性 &#xff0c;但其实从 1.7.20 开始就可以预览了。启动预览需要在 gradle 中升级 KotlinCompileVersion&#xff1a; tasks.withType<KotlinCompile> {kotlinOptions.languageVersion "1.9" }…

四、交换网络实验3——VTP配置

更多网络基础内容可见: 网络基础学习目录及各章节指引 4.6.3 VTP配置 实验目的 学习思科私有协议VTP的配置方法,观察VTP三种工作模式的通信方式 实验工具 Cisco Packet Tracer Student 软件 实验环境 安装模拟器的Windows系统 实验步骤 第一步:根据拓扑图,选择三台同…

老胡的周刊(第097期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 Chat2DB[2] Chat2DB 是一款有开源免费的智能…

二分查找--图文详解

二分查找 1. 什么是二分查找2. 原理3. 例子3.1 当数组长度为奇数3.1 当数组长度为偶数3.3 实现过程 4. 顺序查找与二分查找的区别结束语 1. 什么是二分查找 二分查找也称折半查找&#xff0c;是在一组有序(升序/降序)的数据中查找一个元素&#xff0c;它是一种效率较高的查找方…

chatgpt赋能python:重新配置PyCharm,让你的Python编程更加高效

重新配置PyCharm&#xff0c;让你的Python编程更加高效 PyCharm是一个流行的Python集成开发环境&#xff0c;被广泛用于Python编程。但是&#xff0c;有时候我们需要重新配置PyCharm以适应特定的工作需求或优化其性能&#xff0c;这篇文章将讨论如何重新配置PyCharm&#xff0…

K8S安全管理

1 安全管理 1.1 安全框架 1.1.1 认证框架 学习目标 这一节&#xff0c;我们从 基础知识、认证流程、小结 三个方面来学习。 基础知识 资源操作 用户访问k8s业务应用的流程&#xff1a;方法一&#xff1a;无需api_server认证用户 -- ingress|service -- pod方法二&#xf…

Transformer面试题总结

1.框架 Transformer和seq2seq一样由解码器和编码器组成&#xff0c;用多头注意力替换编码器和解码器架构中最常用的循环层 1.1 编码器&#xff1a;编码器有一堆N6的相同层组成&#xff0c;每一层有两个子层&#xff0c;第一个子层包含多头注意力机制&#xff0c;第二个子层是前…

Spring MVC相关注解运用 —— 中篇

目录 一、RESTful风格支持 1.1 RESTful风格介绍 1.2 postman使用 二、PathVariable 2.1 实例程序 2.2 测试结果 三、PostMapping、GetMapping、PutMapping、DeleteMapping 四、HiddenHttpMethodFilter 4.1 在web.xml配置过滤器 4.2 控制器方法 4.3 JSP页面 4.4 测…

数据库管理工具DBeaver 连接 TDengine详细教程

数据库管理工具DBeaver 连接 TDengine 一、介绍二、前置条件2.1 TDEngine安装 2.2 DBeaver 下载及安装三、DBeaver 连接 TDengine 一、介绍 Dbeaver是一款功能强大的数据库管理工具&#xff0c;支持任何拥有 JDBC-Driver 的数据库。TDengine是一款由涛思数据开发的国产的时序数…

【网络编程】网络编程套接字(二)简单的UDP网络程序

文章目录 服务器编程1.创建服务端套接字2.绑定服务端套接字3.服务端启动 客户端编程1.创建客户端套接字2.绑定客户端套接字 服务器和客户端测试 服务器编程 1.创建服务端套接字 使用socket函数调用可以创建套接字的文件描述符&#xff0c;与前边的文件类似&#xff0c;socket…

【基础算法】递归算法

递归算法是一种直接或间接调用原算法的算法&#xff0c;一个使用函数自身给出定义的函数被称为递归函数。利用递归算法可以将规模庞大的问题拆分成规模较小的问题&#xff0c;从而使问题简化。无论是递归算法还是递归函数&#xff0c;最大的特点都是“自己调用自己”。 斐波那…

nRF52832蓝牙概述

基本概念 RSSI&#xff08;Received Signal Strength Indicator&#xff09;是接收信号的强度指示。 接收包RSSI是指无线模块发送信息后&#xff0c;接收端的无线模块接收到数据后&#xff0c;当前接收数据的信号强度的寄存器值&#xff0c;也就是接收模块获取到发送模块当前发…

Vector - CAPL - 数据库和CAPL_01

目录 获取CAN总线报文信息 静态访问报文信息 动态访问报文信息 静态访问数据库信息 DBLookup&#xff08;Access Message & Signal&#xff09; 1、报文类型信息 2、类型信息 3、节点信息 获取CAN总线报文信息 我们在做CAN网络管理或者通信的测试的过程中&#xf…

LLM prompt提示构造案例

参考&#xff1a; https://github.com/PlexPt/awesome-chatgpt-prompts-zh 吴恩达 prompt工程应用&#xff1a; https://www.bilibili.com/video/BV1No4y1t7Zn prompt构造案例代码 prompt """文本分类任务&#xff1a;将一段用户给外卖服务的评论进行分类…