目录

一、前提  返回目录

经常会遇到登录系统时候需要输入动态验证码的情况,但是自动化如何识别图片然后登陆系统

需要用到pytesseract识别验证码图片以及PIL图像处理方法

import pytesseract
from PIL import Image, ImageEnhance

二、获取验证码  返回目录

1、思路

  • 步骤①:定位图片的元素,并且截取当前浏览器的页面图片
  • 步骤②:获取验证码坐标点,以及验证码图片、浏览器、截图的长和宽
  • 步骤③:截取截图里的验证码图片,获得的验证码图片并保存
  • 步骤④:获得验证码code

2、实践方法

以下步骤都在getCodeImg方法里面:

    def getCodeImg(self):
"""获取验证码"""

1)步骤①

imgPath:浏览器截图图片路径

savePath:保存验证码图片路径

加了一个点击验证码图片方法,目的是为了后面重新获取验证码用的。

        # 步骤①:
basePath = Fun().upPath() + "/utils/img/"
imgPath = basePath + "code.png"
savePath = basePath + "saveCode.png"
# 定位图片元素
imgElement = self.webDriverWait(Loc.codeImg_loc)
# 点击验证码图片
imgElement.click()
# 截取当前页面的图并放到目录里
self.driver.save_screenshot(imgPath)

2)步骤②

获取验证码坐标是为了下面计算验证码占据整个浏览器的百分比。

        # 步骤②:
# 获取验证码x,y轴,x&y代表左上角的坐标点
imgLocation = imgElement.location
print(f"图片坐标点:{imgLocation}")
# 获取验证码长、宽
imgSize = imgElement.size
print(f"图片长、宽:{imgSize}")
# 获取浏览器的长、宽
windowSize = self.driver.get_window_size()
print(f"浏览器长、宽:{windowSize}")
# 打开截图
openImg = Image.open(imgPath)
# 获取保存截图的长、宽(宽:2700, 高:1950)
screenImgSize = openImg.size
print(f"保存截图的长、宽:{screenImgSize}")

3)步骤③

计算图片四个边距在真实浏览器的百分比,用这个百分比乘以浏览器截图的长和宽,得出截图里面的验证码大概位置,然后再自己进行调整截图里的边距大小。

最后再把验证码图片进行图片处理,灰色度和增强对比度等等,提高获取验证码图片的识别率。

        # 步骤③:截取截图的验证码图片
# 图片左边距占据整个浏览器的百分比
left = imgLocation['x']/windowSize['width']
# 图片上边距占据整个浏览器的百分比
top = imgLocation['y']/windowSize['height']
# 图片右边距占据整个浏览器的百分比
right = (imgLocation['x'] + imgSize['width'])/windowSize['width']
# 图片下边距占据整个浏览器的百分比
bottom = (imgLocation['y'] + imgSize['height'])/windowSize['height'] # 需要截取的坐标
screenLocation = (
left * screenImgSize[0],
top * screenImgSize[1]+150,
right * screenImgSize[0],
bottom * screenImgSize[1]+150
)
# 打开截图并截取区域并保存
img = openImg.crop(screenLocation)
img = img.convert('L') # 转换模式:L | RGB      # 提高识别率(见下面)
# enhancer = ImageEnhance.Color(img)
# enhancer = enhancer.enhance(0)
# enhancer = ImageEnhance.Brightness(enhancer)
# enhancer = enhancer.enhance(2)
# enhancer = ImageEnhance.Contrast(enhancer) # 增强对比度
# enhancer = enhancer.enhance(8)
# enhancer = ImageEnhance.Sharpness(enhancer)
# img = enhancer.enhance(20) img = ImageEnhance.Contrast(img) # 增强对比度
img = img.enhance(2.0)
img.save(savePath)

不过识别率还是比较低的,下面有种可以提高识别率的方法,但是见仁见智,实测有时很快有时很慢。

参考文章:

pytesseract 识别率低提升方法

【python图像处理】图像的增强(ImageEnhance类详解)

4)步骤④

获取的验证码可能不是我们想要的,会出现中间有大小空格、换行情况,需要替换掉

    def remove(self,string):
"""字符串去除空格或换行""" str = string.replace(" ", "")  #大空格
str = str.replace("", "")     #小空格
str = str.replace('\n', "")    #换行符
return str def getCodeImg(self):
"""获取验证码""" # 步骤④:获得code验证码
code = pytesseract.image_to_string(img).strip()
print(f"提取的验证码为:【{self.remove(code)}】")
return self.remove(code)

三、获取4位验证码  返回目录

1、思路

  • 因为实际效果我们要获取4位验证码
  • 虽然上一步骤获取到了验证码,但是还是会出现不足4位或者超过4位的验证码
  • 需要进行判断筛选,只要4位的验证码

2、实践方法

先判断是否满足4位,不满足的话while循环重新获取验证码,满足4位跳出循环,并return出来

    def getCode(self):
"""获取4位数验证码""" # 循环前获取code字数
code = self.getCodeImg()
print(f"验证码位数:【{len(code)}】位")
while len(code) != 4:
# 重新获取验证码
code = self.getCodeImg()
# print(f"验证码位数:【{len(code)}】位")
# if len(code) != 4:
# print("验证码不是4位数!")
print(f"输出4位验证码为:{code}")
return code

四、判断验证码是否正确  返回目录

1、思路

  • 虽然我们获取了4位验证码,但是因为识别率的问题,获取的验证码仍然不对,导致提示验证码错误

  • 我们还得重新获取一遍验证码,直到获取成功能够登陆为止

2、实践方法

判断页面如果有错误提示,则重新获取4位验证码

    def checkCode(self):
"""判断验证码是否正确""" try:
errorMsg = self.get_text(Loc.errorMsg_loc)
if errorMsg == "验证码错误":
self.inputCodeAction()
except:
print("验证码正确,进入首页!")

五、输入验证码登录  返回目录

1、思路

  • 封装一个Action方法,把之前的各种方法封装在一起
  • 实现输入验证码登录
  • 此封装方法只是在获取验证码的类里,输入用户名和密码的方法在另一个类里

2、实践方法

    def inputCodeAction(self):
"""输入验证码登录""" code = self.getCode()             # 获取4位验证码
self.el_clear_sendKeys(Loc.code_loc, code) # 清空验证码输入框并输入验证码
self.el_click(Loc.loginButton_loc)      # 点击登录按钮
self.checkCode()                 # 判断验证码是否正确

六、登录页面类  返回目录

登录页面类,封装输入用户名、密码、验证码、登录的操作方法

class LoginPage(BasePage):
"""登录页面""" def login_action(self,username,password):
"""登录操作"""
self.el_sendKeys(Loc.username_loc, username) # 输入用户名
self.el_sendKeys(Loc.password_loc, password) # 输入密码
GetCode(self.driver).inputCodeAction() # 输入验证码并登录

七、完整的获取验证码类代码  返回目录

import pytesseract
from PIL import Image, ImageEnhance
from page_object.page.basePage import BasePage
from page_object.utils.functions import Functions as Fun
from page_object.locator.loginPageLoc import LoginPageLoc as Loc class GetCode(BasePage): def remove(self,string):
"""字符串去除空格或换行""" str = string.replace(" ", "")
str = str.replace("", "")
str = str.replace('\n', "")
return str def getCodeImg(self):
"""获取验证码""" # 步骤①:
basePath = Fun().upPath() + "/utils/img/"
imgPath = basePath + "code.png"
savePath = basePath + "saveCode.png"
# 定位图片元素
imgElement = self.webDriverWait(Loc.codeImg_loc)
# 点击验证码图片
imgElement.click()
# print(f"点击【{next(iter(Fun()))}】次验证码图片")
# 截取当前页面的图并放到目录里
self.driver.save_screenshot(imgPath) # 步骤②:
# 获取验证码x,y轴,x&y代表左上角的坐标点
imgLocation = imgElement.location
print(f"图片坐标点:{imgLocation}")
# 获取验证码长、宽
imgSize = imgElement.size
print(f"图片长、宽:{imgSize}")
# 获取浏览器的长、宽
windowSize = self.driver.get_window_size()
print(f"浏览器长、宽:{windowSize}")
# 打开截图
openImg = Image.open(imgPath)
# 获取保存截图的长、宽(宽:2700, 高:1950)
screenImgSize = openImg.size
print(f"保存截图的长、宽:{screenImgSize}") # 步骤③:截取截图的验证码图片
# 图片左边距占据整个浏览器的百分比
left = imgLocation['x']/windowSize['width']
# 图片上边距占据整个浏览器的百分比
top = imgLocation['y']/windowSize['height']
# 图片右边距占据整个浏览器的百分比
right = (imgLocation['x'] + imgSize['width'])/windowSize['width']
# 图片下边距占据整个浏览器的百分比
bottom = (imgLocation['y'] + imgSize['height'])/windowSize['height'] # 需要截取的坐标
screenLocation = (
left * screenImgSize[0],
top * screenImgSize[1]+150,
right * screenImgSize[0],
bottom * screenImgSize[1]+150
)
# 打开截图并截取区域并保存
img = openImg.crop(screenLocation)
img = img.convert('L') # 转换模式:L | RGB # enhancer = ImageEnhance.Color(img)
# enhancer = enhancer.enhance(0)
# enhancer = ImageEnhance.Brightness(enhancer)
# enhancer = enhancer.enhance(2)
# enhancer = ImageEnhance.Contrast(enhancer) # 增强对比度
# enhancer = enhancer.enhance(8)
# enhancer = ImageEnhance.Sharpness(enhancer)
# img = enhancer.enhance(20) img = ImageEnhance.Contrast(img) # 增强对比度
img = img.enhance(2.0)
img.save(savePath) # 步骤④:获得code验证码
code = pytesseract.image_to_string(img).strip()
print(f"提取的验证码为:【{self.remove(code)}】")
return self.remove(code) def getCode(self):
"""获取4位数验证码""" # 循环前获取code字数
code = self.getCodeImg()
print(f"验证码位数:【{len(code)}】位")
while len(code) != 4:
# 重新获取验证码
code = self.getCodeImg()
print(f"验证码位数:【{len(code)}】位")
if len(code) != 4:
print("验证码不是4位数!")
print(f"输出4位验证码为:{code}")
return code def checkCode(self):
"""判断验证码是否正确""" try:
errorMsg = self.get_text(Loc.errorMsg_loc)
if errorMsg == "验证码错误":
self.inputCodeAction()
except:
print("验证码正确,进入首页!") def inputCodeAction(self):
"""输入验证码登录""" code = self.getCode()
self.el_clear_sendKeys(Loc.code_loc, code)
self.el_click(Loc.loginButton_loc)
self.checkCode()

八、附录:静态图片文字提取  返回目录

1、思路:

  • 首先获取图片的src地址
  • 然后进行GET接口请求,获取图片的二进制数据
  • 再创建一个图片文件,把二进制数据写到图片里
  • 最后读取图片,获取验证码code

2、实践方法

获取图片地址,有两种情况,一种是通过解析页面获取src,一种是通过页面元素获取src

1)获取src

①通过前端页面代码获取src

这种方式比较简单,直接通过前端页面代码获取src

    headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
}
# 打开登录页面地址
url = 'https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx'
# 获取前端页面代码
page_text = requests.get(url=url, headers=headers).text
# 解析字符串格式的HTML文档对象
tree = etree.HTML(page_text)
# 解析出页面中图片的地址
cod_img_src ='https://so.gushiwen.cn' + tree.xpath('//*[@id="imgCode"]/@src')[0]

注:etree.HTML()可以用来解析字符串格式的HTML文档对象,将传进去的字符串转变成_Element对象。作为_Element对象,可以方便的使用getparent()、remove()、xpath()等方法。

②页面元素获取src

当获取不到前端代码时候,可以用Selenium自动化获取元素属性值

    headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.102 Safari/537.36'
}
# 打开浏览器
driver = webdriver.Chrome()
# 浏览器打开登录地址
driver.get("https://so.gushiwen.cn/user/login.aspx?from=http://so.gushiwen.cn/user/collect.aspx")
# CSS定位元素,获取src属性值
src = driver.find_element_by_css_selector("#imgCode").get_attribute("src")

2)获取图片二进制数据

cod_data = requests.get(url=src,headers=headers).content

打印结果:

b'GIF89a7\x00\x16\x00\xf7\x00\x00\x00\x00\x00\x00\x003\x00\x00f\x00\x00\x99\x00\x00\xcc\x00\x00\xff\x00+\x00\x00+3\x00+f\x00+\x99\x00+\xcc\x00+\xff\x00U\x00\x00U3\x00Uf\x00U\x99\x00U\xcc\x00U\xff\x00\x80\x00\x00\x803\x00\x80f\x00\x80\x99\x00\x80\xcc\x00\x80\xff\x00\xaa\x00\x00\xaa3\x00\xaaf\x00\xaa\x99\x00\xaa\xcc\x00\xaa\xff\x00\xd5\x00\x00\xd53\x00\xd5f\x00\xd5\x99\x00\xd5\xcc\x00\xd5\xff\x00\xff\x00\x00\xff3\x00\xfff\x00\xff\x99\x00\xff\xcc\x00\xff\xff3\x00\x003\x0033\x00f3\x00\x993\x00\xcc3\x00\xff3+\x003+33+f3+\x993+\xcc3+\xff3U\x003U33Uf3U\x993U\xcc3U\xff3\x80\x003\x8033\x80f3\x80\x993\x80\xcc3\x80\xff3\xaa\x003\xaa33\xaaf3\xaa\x993\xaa\xcc3\xaa\xff3\xd5\x003\xd533\xd5f3\xd5\x993\xd5\xcc3\xd5\xff3\xff\x003\xff33\xfff3\xff\x993\xff\xcc3\xff\xfff\x00\x00f\x003f\x00ff\x00\x99f\x00\xccf\x00\xfff+\x00f+3f+ff+\x99f+\xccf+\xfffU\x00fU3fUffU\x99fU\xccfU\xfff\x80\x00f\x803f\x80ff\x80\x99f\x80\xccf\x80\xfff\xaa\x00f\xaa3f\xaaff\xaa\x99f\xaa\xccf\xaa\xfff\xd5\x00f\xd53f\xd5ff\xd5\x99f\xd5\xccf\xd5\xfff\xff\x00f\xff3f\xffff\xff\x99f\xff\xccf\xff\xff\x99\x00\x00\x99\x003\x99\x00f\x99\x00\x99\x99\x00\xcc\x99\x00\xff\x99+\x00\x99+3\x99+f\x99+\x99\x99+\xcc\x99+\xff\x99U\x00\x99U3\x99Uf\x99U\x99\x99U\xcc\x99U\xff\x99\x80\x00\x99\x803\x99\x80f\x99\x80\x99\x99\x80\xcc\x99\x80\xff\x99\xaa\x00\x99\xaa3\x99\xaaf\x99\xaa\x99\x99\xaa\xcc\x99\xaa\xff\x99\xd5\x00\x99\xd53\x99\xd5f\x99\xd5\x99\x99\xd5\xcc\x99\xd5\xff\x99\xff\x00\x99\xff3\x99\xfff\x99\xff\x99\x99\xff\xcc\x99\xff\xff\xcc\x00\x00\xcc\x003\xcc\x00f\xcc\x00\x99\xcc\x00\xcc\xcc\x00\xff\xcc+\x00\xcc+3\xcc+f\xcc+\x99\xcc+\xcc\xcc+\xff\xccU\x00\xccU3\xccUf\xccU\x99\xccU\xcc\xccU\xff\xcc\x80\x00\xcc\x803\xcc\x80f\xcc\x80\x99\xcc\x80\xcc\xcc\x80\xff\xcc\xaa\x00\xcc\xaa3\xcc\xaaf\xcc\xaa\x99\xcc\xaa\xcc\xcc\xaa\xff\xcc\xd5\x00\xcc\xd53\xcc\xd5f\xcc\xd5\x99\xcc\xd5\xcc\xcc\xd5\xff\xcc\xff\x00\xcc\xff3\xcc\xfff\xcc\xff\x99\xcc\xff\xcc\xcc\xff\xff\xff\x00\x00\xff\x003\xff\x00f\xff\x00\x99\xff\x00\xcc\xff\x00\xff\xff+\x00\xff+3\xff+f\xff+\x99\xff+\xcc\xff+\xff\xffU\x00\xffU3\xffUf\xffU\x99\xffU\xcc\xffU\xff\xff\x80\x00\xff\x803\xff\x80f\xff\x80\x99\xff\x80\xcc\xff\x80\xff\xff\xaa\x00\xff\xaa3\xff\xaaf\xff\xaa\x99\xff\xaa\xcc\xff\xaa\xff\xff\xd5\x00\xff\xd53\xff\xd5f\xff\xd5\x99\xff\xd5\xcc\xff\xd5\xff\xff\xff\x00\xff\xff3\xff\xfff\xff\xff\x99\xff\xff\xcc\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\xfc\x00,\x00\x00\x00\x007\x00\x16\x00\x00\x08\xff\x00\x95\x11\x13Hp\xa0\xc1\x82\x08\x0f*L\xc8p\xa1\xc3}\x10#J\xfc$1\x93\xb2}\x99$\xee\xa3\x08\xd1\xa2\xc6\x8f 5\x12\xe3\xf8\xf1\x13\xb1\x8f\x03\xf7)\xcb\x08\xf1dD\x96!cJ\x14\x08\xd2%H\x8b\'W\xb6\x84x\xd1\xa6L\x8c\x175z\xd4H2d\xce\xa3\x1c]\xc2\x04\xb92\xe8G\x9a\x115a)\xb0i\x1f1P\xbe\x06\xb8x`\xb0\xd1\x80\x16-\xe0\x10K6P\x930\x16V\xd0\x02\xe9\xa8\xefO\x951\x9a \xea\xf3S\xa5\xaa\xc4\x91\x11\x93\xed\x1bD\xe0\x0eDw\x04\\\xec\x88\x06\xb1\x17X\xb0,\xe0\xc4%\xc6\xa8\x85\x15\xc7hYh\x1ak\xa5\x8a\x15Md\x93\xfd\xa1BI\'O\x97\x93\x95\xb9 PU\x9f\x0b\x17\x10"\xea\xc3\xd2"\xd4\xbeF-t\xa8\x94\xe4X\x8d\\@V\xba|j[y\x0c\xe1\xb6U\x96\t\x15\xa8\x17b\x16\x17F\x88aA\x1d\x13\xb6m}\x81X\xc4\xb1J\xfc\x0f\x0bJ\xfa\x00U\xd9^:\x15\x15\xbb\x11\xa1F\xff\xc4Bz\xb4\x8b\xc9\xa0\xee\xea\xbb\xd2b\xc6>M\xfa\x1ek\x1a\x96\xfe\xaa-+cx3\xaar%\x1ap\xe1w\xa5\'\x91 \x05\x04\x16\x98\x05-\r\xa3\x8c&\xca\xb8s\xd8)\xfb\xf4\xf2X}\x11\xf1b\x85\x0e\xc9h\xa7\x89[\xf0yW\xd5HGiD\x9e\x0b\x05h2\x9ak;\xed\xa3\xe0$\xed\x11\x93I\x0b\xfdAD\x962\xc2\xe0\xc7[(\xedX\xa6L\x15\x7fLvWq\x11\x1dW\x00a\x8e\xb8\xa0\x03aA1\xb8\x0f=\xec\xcdwEb61\xc6\x02\x19\xc9T\xd6Y!U\x88\xb1YU8\xa9\xe4\xd3>\xe4\xd9\x05\x98\x0bj\xe8\xe5\xa0\x0b\xd1\x103\x0cX\xa7\xacgE\x99\x0cfRe\x15\x9ad\xe2\x16\x1c\xc3\xe4\xe3\x16\x87>e"\xa0\x8a\xca\x1c\x07\x04A\x88\xb4@\x80&\x93\xb1\xe7W;`M\xd6\x0b\x0b\xd2\x11g\xc5\xa4\x98Y)\xd0.\xdb}w\x97x\x10\x91\x07GT\xa7\xfd\xa0\xcc0\xb0\x1d\x16\xd6X\x8c=\x99\xd6\xa4\x97\x8d\xfa\x87\x15v\r\x89\xb3\'\x8ax\xa5$\x11_q\x0cc\xd5>\xbe\xb4\xe0\x02\x84\xfbPr\x98]\xe9)\xf3\xe8\xaa9\xa8\xa6\xdd$\xa0\x0c\x14\xc9\x96\x80~\x16\x93S\xd3\xa2\xeaSA\xa0\xd07P\xb3-\x05\xb5`Dx\xfd\xa4\x11B\n2\x88\x19\x83_\xf2\xa4+D\x02\x1a4S\xba\x1aaF\x0c\x83\xc3\x9c+\xd1\xba\xe2\xde\xab\xd2P\x11)h\x94I\xf9R\x9b\xef>\xdc^\x84\xaf\x97&5\x05"A\xda\x8e\xda\xac@&5K/\xc4c\xd1\xdb\xec\xc2\nV|\xd5U\xe5\x12\x13\x10\x00;'

3)数据写入到图片中,并识别验证码

    # 读取二进制数据写入到图片中
with open('./code.jpg', 'wb') as fp:
fp.write(cod_data)
# 识别图片中的文字
text = pytesseract.image_to_string(Image.open(r'./code.jpg'))

3、总结

但是这种通过接口方式获取的验证码并不是你想要的,因为每请求一次接口,图片就会发生变化,所以只能适用于静态不变的图片比较合适。

参考文章:《Pytesseract的安装与使用

【Python】Selenium自动化测试之动态识别验证码图片方法(附静态图片文字获取)的更多相关文章

  1. Python+Selenium自动化-设置等待三种等待方法

    Python+Selenium自动化-设置等待三种等待方法   如果遇到使用ajax加载的网页,页面元素可能不是同时加载出来的,这个时候,就需要我们通过设置一个等待条件,等待页面元素加载完成,避免出现 ...

  2. python selenium自动化测试之路(1)--分层测试概念、selenium工具介绍

    1.分层自动化测试概念 传统的自动化市场更关注产品UI层的自动化测试,而分层的自动化测试倡导产品开发的不同阶段都需要自动化测试 大多公司与研发团队其实是忽略了单元测试与集成测试阶段的自动化测试工作,所 ...

  3. Python+selenium自动化测试之浏览器基础操作

    **​​前言** 本文主要讲解webdriber框架,Selenium 就像真实用户所做的一样,Selenium 测试可以在 Windows.Linux 和 Macintosh上的 Internet ...

  4. Python&Selenium自动化测试之PO设计模式

    一.摘要 Page Object模式,后面简称PO,他是一种设计思想,在上一章节中,曾经列举了一些在编写自动化测试过程中随着代码量的增加导致的大量代码难以维护.难以扩展.可读性极差等灾难性的事件:那么 ...

  5. python+selenium自动化测试之登录

    selenium_login.py import unittest from selenium import webdriver class LoginTest(unittest.TestCase): ...

  6. python接口自动化(Cookie_绕过验证码登录)

     python接口自动化(Cookie_绕过验证码登录) 有些登录的接口会有验证码,例如:短信验证码,图形验证码等,这种登录的验证码参数可以从后台获取(或者最直接的可查数据库) 获取不到也没关系,可以 ...

  7. python selenium自动化点击页面链接测试

    python selenium自动化点击页面链接测试 需求:现在有一个网站的页面,我希望用python自动化的测试点击这个页面上所有的在本窗口跳转,并且是本站内的链接,前往到链接页面之后在通过后退返回 ...

  8. selenium自动化测试之整合测试报告

    selenium自动化测试之整合测试报告 标签(空格分隔): 整合报告 如下截图我们添加一个文件叫做:latest_report.py文件, import time import os import ...

  9. Python+Selenium爬取动态加载页面(2)

    注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...

  10. Python+Selenium爬取动态加载页面(1)

    注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...

随机推荐

  1. 🚀 Karpor - 让 AI 全面赋能 Kubernetes!

    什么是 Karpor? 一言以蔽之,Karpor 是一个现代化的 Kubernetes 可视化工具,核心特性聚焦在  搜索. 洞察. AI ,目标是更方便快捷地连接平台和多集群,并用 AI 赋能 Ku ...

  2. AIGC的行业发展

    1. AIGC的行业发展 AIGC(Artificial Intelligence Generated Content,人工智能生成内容)是利用人工智能技术来自动生成内容的一种新型内容创作方式.它基于 ...

  3. 高程读后感(四)— 关于BOM本人容易忽略的知识点总结

    目录 window对象 window对象上属性及方法 超时调用setTimeout和间歇调用setInterval BOM location对象及其位置操作 history对象 window对象 wi ...

  4. [oeasy]python0015_十六进制_hexadecimal_字节形态_hex函数

    ​ 十六进制(hexadecimal) 回忆上次内容 上次数制可以转化 bin(n)可以把数字转化为 ​​2进制​ binary 接收一个整数(int) 得到一个二进制数形式的字符串 ​ 编辑 数字在 ...

  5. 🚀RabbitMQ+redis+Redisson分布式锁+seata实现订单服务

    引言 订单服务涉及许多方面,分布式事务,分布式锁,例如订单超时未支付要取消订单,订单如何防止重复提交,如何防止超卖.这里都会使用到. 开启分布式事务可以保证跨多个服务的数据操作的一致性和完整性, 使用 ...

  6. OLOR:已开源,向预训练权值对齐的强正则化方法 | AAAI 2024

    随着预训练视觉模型的兴起,目前流行的视觉微调方法是完全微调.由于微调只专注于拟合下游训练集,因此存在知识遗忘的问题.论文提出了基于权值回滚的微调方法OLOR(One step Learning, On ...

  7. php8.3开启jit技术

    查看是否开启:$jitEnabled = ini_get('jit.enabled'); echo "JIT Enabled: " . ($jitEnabled == '1' ? ...

  8. (2024最新)有效解决OpenAI Chatgpt Plus升级报错【您的银行卡被拒绝了/your card has been declined」,不用再问怎么办?

    在OpenAI升级ChatGPT plus时我们可能会遇到升级报错[您的银行卡被拒绝了/your card has been declined」,有些人看到这个可能就会不知所措 注意,这个问题目前依旧 ...

  9. 【Java】 Void 类型

    void 也算一个类型,而且是基本数据类型 和其它数据类型一样提供了对应的包装类Void 每个包装类都提供一个TYPE字节实例,返回对应的原型类实例 public static void main(S ...

  10. 深度学习框架theano下的batch_norm实现代码——强化学习框架rllab

    深度学习框架theano下的batch_norm实现代码--强化学习框架rllab # encoding: utf-8 import lasagne.layers as L import lasagn ...