爬虫进阶-反爬破解6(Nodejs+Puppeteer实现登陆官网+实现滑动验证码全自动识别)
一、Nodejs+Puppeteer实现登陆官网
1.环境说明
Nodejs——直接从官网下载最新版本,并安装
使用npm安装puppeteer:npm install puppeteer
npm install xxx -registry https://registry.npm.taobao.org
Chromium会自动下载,前提是网络通畅
2.实践操作:Nodejs+Puppeteer介绍
Puppeteer登录官网首页:
1.打开浏览器并访问首页
2.键入数据并访问登录后的页面
3.截图保留记录,存储成本地图片
const puppeteer = require("puppeteer")const sleep = time => new Promise(resolve => {setTimeout(resolve, time);
});(async() => {const browser = await puppeteer.launch({headless:false,//无头模式,默认是隐藏界面的,true.改成false,显示界面。slowMo:100 //设置浏览器每一步之间的时间间隔,单位毫秒defaultViewport:{width:1366, height:768},//默认的网页大小是800*800,可以自行设置});const page = await browser.newPage();await page.goto("http://shanzhi.spbeen.com/index");await sleep(3000);const login_link_button = await page.$('a.btn.btn-primary');await login_link_button.click()await sleep(2000);const username_input = await page.$('input#username');await username_input.type('demo1234');await sleep(2000);const password_input = await page.$('input#MemberPassword');await password_input.type('demo1234');await sleep(2000);const submit_button = await page.$("button.btn.btn-primary");await submit_button.click(); await sleep(2000);await page.screenshot({path:'shanzhi_login_index.png'});await sleep(2000);await browser.close();})();
3.总结:
Puppeteer有更多且更全的接口,可以快捷的操作网页
Puppeteer可以实现多种数据的存储,例如截图、pdf等
浏览器的标签页不要太多,容易卡电脑
二、nodejs+puppeteer实现滑动验证码全自动识别
1.滑动验证码破解方法
数据来源:滑动验证码的图片偏移
破解方法一:分析请求,用数据做正确的请求操作
破解方法二:浏览器实现滑动验证码
2.滑动验证码偏移计算方法
数据来源:滑动验证码的图片
方法一:相似度对比
方法二:像素的RGB值对比
方法三:调用经过数据训练过的机器学习模型
3.图片的预处理
数据来源:滑动验证码的图片
阶段一:缩放图片[将图片尺寸进行压缩]
阶段二:简化色彩[灰度处理]
阶段三:计算平均值或灰度平均值
4.实践操作:图形以及效果展示
// const puppeteer = require("puppeteer");//puppeteer启动的chromium会被知乎识别const puppeteer = require('puppeteer-extra');//消除特征 npm install puppeteer-extra
const StealthPlugin = require('puppeteer-extra-plugin-stealth'); //npm install puppeteer-extra-plugin-stealth
puppeteer.use(StealthPlugin()); //消除特征const Rembrant = require('rembrandt');//rembrandt算法库,导入使用 npm install rembrandt
const fs = require('fs');// nodejs 操作本地文件的库 npm install fs
var ssim = require('ssim');//ssim算法库,导入使用 npm install ssim// 睡眠函数,单位毫秒
const sleep = time => new Promise(resolve => {setTimeout(resolve, time);
});//程序的主体部分
(async() => {const browser = await puppeteer.launch({//启动浏览器headless:false,//无头模式,默认是隐藏界面的,true.改成false,显示界面。defaultViewport:{width:1366, height:768},//默认的网页大小是800*800,可以自行设置args: ['--disable-web-security','--disable-features=IsolateOrigins,site-per-process',]});const page = await browser.newPage();await page.goto("http://www.zhihu.com/signin");//点击“密码登录”,从“手机短信登陆”切换到“账号密码登录”const mima_button = await page.$('form.SignFlow.Login-content > div:nth-child(1) div:nth-child(2)');await mima_button.click;const username = await page.$('div.SignFlow-account input.Input');await username.type('18296198879');const password = await page.$('div.SignFlow-password input.Input');await password.type('demodemodemo');// 定位登录按钮,点击登录,弹出滑动验证码,开始验证const login_button = await page.$('button.Button.SignFlow-submitButton.Button--primary.Button--blue');await sleep(1000)await login_button.click()await sleep(1000);// 重复破解 滑块验证码 代码部分for (let num = 1; num < 1000; num++){await sleep(2000);console.log('----------------\n当前循环次数:',num);// 判断 验证码多次失败后,弹出的错误提示,需要点击之后才能继续验证// 判断依据 “失败过多,点此重试”,然后会恢复到等到滑块滑动的验证状态let yidun_msg = await page.$eval("span.yidun_tips_text.yidun-fallback_tip",el => el.innerHTML)if (yidun_msg = '失败过多,点此重试'){const yidun_tips = await page.$(".yidun_tips");await yidun_tips.click();};// 验证成功后,滑动验证码的框会隐藏// 如果滑动验证码隐藏了,则自动停止,并输出“验证成功,正常退出”let yidun_popup = await page.$('div.yidun_popup--light.yidun_popup');const yidun_popup_style = await page.evaluate(//根据yidun_popup标签,通过window窗口,计算出标签的style样式(x) => {return JSON.parse(JSON.stringify(window.getComputedStyle(x)))},yidun_popup);console.log('yidun_popup style.display:',yidun_popup_style.display);//输出样式值if(yidun_popup_style.display == 'none'){console.log("验证成功,正常退出");break;// 如果样式值为none,则表示验证成功了,使用break跳出for循环};// page.waitForSelector('.yidun_tips', {timeout:1000}).then((yidun_tips) => yidun_tips.click());//calculateDistance函数中的console.log内容全部输出在网页的开发者工具console栏【记得拉长延迟,慢慢看】calculateDistance = async (page) =>{var distance = await page.evaluate(() => {//将图片写入canvas,截取canvas的图片内容,通过toGrayBinary全部换成二维数组,进行像素RGB的对比toGrayBinary = (pixels, binary, value, sn) => {var r, g, b, g, avg = 0, len = pixels.length, s = '';for (var i = 0;i < len; i+= 4){avg += (.299 * pixels[i] + .587 * pixels[i+1]+.114*pixels[i+2]);}avg /= (len /4);for (var i=0;i<len;i+=4){r = .299*pixels[i],g = .587* pixels[i+1],b = .114*pixels[i+2];if (binary){if ((r+g+b)>=(value||avg)){g = 255;if (sn) s+= '1';} else { g = 0;if (sn) s+= '0';}g = (r+g+b) > (value || avg)?255:0;}else{g = r+g+b;}pixels[i] = g,};//将截取的canvas图片,转成base64,方便存储本地imgCanvasToBase64 = (img,width,height) => {let canvas3 = document.createElement("canvas");let context3 = canvas3.getContext("2d");canvas3.width = width;canvas3.height = height;context3.putImageData(img,0,0,0,0,width,height);let base64Img = canvas3.toDataURL('image/jpeg');return base64Img;};const smallbgimg = document.getElementByClassName('yidun_jigsaw')[0];//提取图片const smallcanvas = document.createElement('canvas');//创建画布const smallcontext = smallcanvas.getContext('2d');//设定2d界面console.log('smallbgimg:', smallbgimg, smallbgimg.naturalWidth, smallbgimg.naturalHeight);smallcontext.drawImage(smallbgimg,0,0,smallbgimg.naturalWidth, smallbgimg.naturalHeight);//写入图片到画布中//将图片亮度降低,颜色减弱【灰度处理】//从0,0位置,读取图片的宽高var pixels = smallcontext.getImageData(0,0,smallbgimg.naturalWidth, smallbgimg.naturalHeight);var pixeldata = pixels.data;//读取了图片,取出具体的数值data//循环设置,降低像素的RGB值。RGB分别是0,1,2//完整的值,是RGBA,A一直是1,所以不需要处理A,所以i每次增加4for (var i=0,len = pixeldata.length;i<len;i+=4){pixels.data[i] = pixels.data[i] - 95;//Rpixels.data[i+1] = pixels.data[i+1] - 55;//Gpixels.data[i+2] = pixels.data[i+2] -45;//B}smallcontext.putImageData(pixels,0,0); //把数据写回到画布中var minwidth = smallbgimg.naturalWidth;var maxwidth = 0;var minheight = smallbgimg.naturalHeight;var maxheight = 0;for (let i = 1;i<smallbgimg.naturalWidth;i++){let times=0;//因为缺口只会出现在中间位置,所以不用对比整个纵坐标,只需要对比中间位置即可//这里我们从上面45像素开始到下面55像素结束for (let j=1;i<smallbgimg.naturalHeight;j++){const smallimgData = smallcontext.getImageData(1*i,1*j,1,1).data:const r = smallimgData[0];const g = smallimgData[1];const b = smallimgData[2];if (r >0&g>0&b>0){//不含无色的长方形图片if(minwidth >i){minwidth=i;}if(maxheight<=j){maxheight=j;}if(maxwidth<i){maxwidth=i};if(minheight>j){minheight=j};};};};//maxheight = maxheight-12//minwidth = minwidth+2//minheight = minheight +2//maxwidth = maxwidth -2console.log("图片最大和最小宽高",minwidth,maxwidth,minheight,maxheight)var height = maxheight -minheight;var width = maxwidth - minwidth;var smallimg = smallcontext.getImageData(minwidth,minheight,width,height);var smallimgdata = smallimg.data;var smallimggb = toGratBinary(smallimgdata);//console.log('smallimggb',smallimggb)var small_img_canvas = imgCanvasToBase64(smallimg,width,height);console.log('smallimg canvas),small_img_canvas);//背景图转canvasconst bgimg = document.getElementsByClassName('yidun_bg-img')[0];console.log('bgimg',bgImg.naturalWidth,bgImg.naturalHeight);const convas = document.createElement('canvas');const context = canvas.getContext('2d');context.drawImage(bgImg,0,0,bgImg.naturalWidth,bgImg.naturalHeight);const contextBigimg = context.getImageData(1,1,bgImg.naturalWidth,bgImg.naturalHeight);var bigimg = imgCanvasToBase64(contextbigimg,bgImg.naturalWidth,bgImg.naturalHeight);console.log("bigimg canvas:",bigimg);var xAxis = [];var tmpmax = 0.0;var part_bigimg = {};//这个for循环,进行的就是图片二维数组的对比,找出最大的相似度//将截图的canvas图片,放入part_bigimg对象,方便返回并保存成本地图片for (let i = minwidth+width+2;i<bgImg.naturalWidth-width;i++){let times=0;i = minheight +2;const bigimg = context.getImageData(1*i,1*j,width,height);//根据小图的尺寸截取大图的部分内容,能得到小图同高不同宽的逐帧所有同尺寸图片const bigimgData = bigimg.data;const imggb = toGrayBinary(bigimgData);let similar = 0;for (let n=0,len = width*height;n<len;n++){if(smallimggb[n]==imggb[n]){similar++};}similar = (similar/(width*height))*100;var bigimg_part = imgCanvasToBase64(bigimg,width,height);part_bigimg[i] = bigimg_part;if (parseFloat(similar)>tmpmax){tmpmax = parseFloat(similar);console.log('yes:',i,j,width,height,similar,bigimg_part);xAxis = [];xAxis.push(i);} else if(parseFloat(similar)==tmpmax){console.log('yes:',i,j,width,height,similar,bigimg_part);xAxis.push(i);} else{console.log('error---',i,j,width,height,similsr,bigimg_part);};};return [xAxis[xAxis.length-1],small_img_canvas,part_bigimg];//返回多个参数,请修改这里});return distance;//这里不影响结果值的返回}//const distance = await calculateDistance(page);const adata = await calculateDistance(page);const distance = adata[0];const smallimg = adata[1];//base64的小图数据const part_bigimg = adata[2];//base64的截取大图特定部分的所有图片,用于对比小图// const distance, smallimg, part_bigimg = await calculateDistance(page);console.log('像素RGB值对比算法结果值:',distance);//小图存储地址, 保存到本地var small_img_path = './assets/smallimg.jpg';// console.log('smallimg:', smalling);var small_img_data = smallimg.replace("data:image/jpeg;base64,","")const smallimg_buffer = new Buffer.from(small_img_data,'base64');fs.writeFile(small_img_path, smallimg_buffer, function(err){//用fs写入文件//if(err) { console.log(err);}else{// console.log('写入成功!');//}});var maxdiff = 0.0;var offset_size = 0;var ssim_maxdiff = 0.0;var ssim_offset_size = 0;for (var partb in part_bigimg){//截取的所有大图, 保存本地var part_big_img_path = './assets/part_big/'+parseInt(partb)+'.jpg';var part_big_img_data = part_bigimg[partb].replace("data:image/jpeg;base64,","")const partbimg_buffer = new Buffer.from(part_big_img_data,'base64');fs.writeFile(part_big_img_path, partbimg_buffer, function(err){//用fs写入文件//if(err) { console.log(err);}else{// console.log('写入成功!');//}});//ssim算法 比较图片相似度//参数是base64转换成图片字节,也是通过路径读取到的图片内容const ssim_result = ssim(smallimg_buffer, partbimg_buffer);//console.log("ssim:",ssim_result,part_big_img_path);if (ssim_result>ssim_maxdiff){ssim_maxdiff = ssim_result;ssim_offset_size=parseInt(partb);}//randbrandt算法,参数是图片路径const rembrandt = new Rembrandt({imageA:small_img_path,imageB:part_big_img_path,thresholdType:Rembrandt.THRESHOLD_PIXELS//thresholdType:Rembrandt.THRESHOLD_PERCENT});let result = await rembrant.compare();let difference = result.percentageDifference*100;if (difference > maxdiff){maxdiff = difference;offset_size=parseInt(partb);}};console.log("{*}SSIM算法计算偏移结果值:", ssim_offset_size);console.log("rembrandt算法计算偏移结果值:", offset_size);await sleep(1000);// 拿到了滑动验证码的偏差值,开始使用鼠标移动滑块,定位到偏差值的具体位置。const _moveTrace = function* (dis) {//定义移动函数,从起始地址到目标地址,中间要计算出很多个坐标,结合延迟,达到缓慢的滑块效果let trace = [];let t0 = 0.2;let curr = 0;let step = 0;let a = 0.8;while (curr < dis){let t = t0 * (++step);curr = parseFloat((1/2*a*t*t).toFixed(2));trace.push(curr);};for (let i = 0;i<trace.length;++i){yield trace[i];};};const yidun_slider = await page.$(".yidun_slider");// 定位滑块标签位置const bounding_box = await yidun_slider.boundingBox();// 通过bounding_Box()函数,拿到标签的起始坐标,标签的左上角await page.mouse.move(bounding_box.x + bounding_box.width/2,bounding_box.y+bounding_box.height/2);//等待页面上,鼠标移动到标签的中间位置await page.mouse.down();//鼠标按住滑块let gen = _moveTrace(ssim_offset_size);for (let ret of gen){//循环读取_moveTrace返回的生成器的值,每次都挪动一点点。而且y轴【垂直方向】也需要加一个简单的偏移await page.mouse.move(bounding_box.x+ret,bounding_box.y+6);//移动鼠标};await page.mouse.move(bounding_box.x+ssim_offset_size,bounding_box.y+6);//把鼠标移动到目标位置上await.sleep(100);//睡眠100毫秒await page.mouse.up();//到了目标位置上,松开鼠标按键,完成滑块的拖动};await sleep(2000);await browser.close();})();
总结:
使用canvas进行图片的灰度处理、剪辑处理。
图片的对比,要查看算法函数的调用方法,注意数据类型要对上。
修改代码前,要详细阅读每一行代码,修改起来会更顺畅
三、滑动验证码之像素RGB对比算法实现
算法介绍:1.拿到小图,减弱图片颜色2.根据小图的宽高,截图同等宽高的对比图3.循环取出图片的所有RGB值并比较4.取出相似度最大的一个偏移值,做滑动操作
对比步骤:1.图片预处理2.逐个像素对比3.将相似度最大的偏移量进行滑动操作
图片预处理:1.颜色减弱2.宽高设定
相关文章:
爬虫进阶-反爬破解6(Nodejs+Puppeteer实现登陆官网+实现滑动验证码全自动识别)
一、NodejsPuppeteer实现登陆官网 1.环境说明 Nodejs——直接从官网下载最新版本,并安装 使用npm安装puppeteer:npm install puppeteer npm install xxx -registry https://registry.npm.taobao.org Chromium会自动下载,前提是网络通畅 2.实践操作…...
【Unity】RenderFeature笔记
【Unity】RenderFeature笔记 RenderFeature是在urp中添加的额外渲染pass,并可以将这个pass插入到渲染列队中的任意位置。内置渲染管线中Graphics 的功能需要在RenderFeature里实现,常见的如DrawMesh和Blit 可以实现的效果包括但不限于 后处理,可以编写…...
golang gin——controller 模型绑定与参数校验
controller 模型绑定与参数校验 gin框架提供了多种方法可以将请求体的内容绑定到对应struct上,并且提供了一些预置的参数校验 绑定方法 根据数据源和类型的不同,gin提供了不同的绑定方法 Bind, shouldBind: 从form表单中去绑定对象BindJSON, shouldB…...
办公技巧:Excel日常高频使用技巧
目录 1. 快速求和?用 “Alt ” 2. 快速选定不连续的单元格 3. 改变数字格式 4. 一键展现所有公式 “CTRL ” 5. 双击实现快速应用函数 6. 快速增加或删除一列 7. 快速调整列宽 8. 双击格式刷 9. 在不同的工作表之间快速切换 10. 用F4锁定单元格 1. 快速求…...
【jvm--方法区】
文章目录 1. 栈、堆、方法区的交互关系2. 方法区的内部结构3. 运行时常量池4. 方法区的演进细节5. 方法区的垃圾回收 1. 栈、堆、方法区的交互关系 方法区的基本理解: 方法区(Method Area)与 Java 堆一样,是各个线程共享的内存区…...
智慧楼宇3D数据可视化大屏交互展示实现了楼宇能源的高效、智能、精细化管控
智慧园区是指将物联网、大数据、人工智能等技术应用于传统建筑和基础设施,以实现对园区的全面监控、管理和服务的一种建筑形态。通过将园区内设备、设施和系统联网,实现数据的传输、共享和响应,提高园区的管理效率和运营效益,为居…...
算法题:摆动序列(贪心算法解决序列问题)
这道题是一道贪心算法题,如果前两个数是递增,则后面要递减,如果不符合则往后遍历,直到找到符合的。(完整题目附在了最后) 代码如下: class Solution(object):def wiggleMaxLength(self, nums):…...
接口自动化测试yaml+requests+allure技术,你学会了吗?
前言 接口自动化测试是在软件开发过程中常用的一种测试方式,通过对接口进行自动化测试,可以提高测试效率、降低测试成本。在接口自动化测试中,yaml、requests和allure三种技术经常被使用。 一、什么是接口自动化测试 接口自动化测试是指通…...
android 获取局域网其他设备ip
Android 通过读取本地Arp表获取当前局域网内其他设备信息_手机查看arp-CSDN博客...
angular中使用 ngModel 自定义组件
要创建一个自定义的 Angular 组件,并使用 ngModel 进行双向数据绑定,您可以按照以下步骤操作: 创建自定义组件:首先,使用 Angular CLI 或手动创建一个新的组件。在组件的模板中,添加一个输入元素或其他适合…...
kubernetes pod日志查看用户创建
目录 1.创建用户 1.1证书创建 1.2创建用户 1.3允许用户登陆 1.4切换用户 1.5删除用户 2.RBAC 1.创建用户 1.1证书创建 进入证书目录 # cd /etc/kubernetes/pki创建key # openssl genrsa -out user1.key 2048 Generating RSA private key, 2048 bit long modulus .....…...
HTML5+CSSday4综合案例二——banner效果
bannerCSS展示图: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wi…...
关于红包雨功能的探索
【高并发优化手段】基于Springboot项目 【红包雨功能的】环境部署(弹性伸缩、负载均衡、Redis读写分离、云服务器部署) jemeter压测【2万用户每秒5次请求在30秒内处理完请求】 【红包雨压测】提供2万用户30秒内5次请求的并发服务支持 使用工厂模式、策略…...
【已解决】Python打包文件执行报错:ModuleNotFoundError: No module named ‘pymssql‘
【已解决】Python打包文件执行报错:ModuleNotFoundError: No module named pymssql 1、问题2、原因3、解决 1、问题 今天打包一个 tkinter pymssql 的项目的时候,打包过程很顺利,但是打开软件的时候,报错 ModuleNotFoundError: …...
华为云云耀云服务器L实例评测|测试CentOS的网络配置和访问控制
目录 引言 1 理解几个基础概念 2 配置VPC、子网以及路由表 3 配置安全组策略和访问控制规则 3.1 安全组策略和访问控制简介 3.2 配置安全组策略 3.3 安全组的最佳实践 结论 引言 在云计算时代,网络配置和访问控制是确保您的CentOS虚拟机在云环境中安全运行的…...
CSP模拟51联测13 B.狗
CSP模拟51联测13 B.狗 文章目录 CSP模拟51联测13 B.狗题目大意题目描述输入格式输出格式样例样例 1inputoutput 思路 题目大意 题目描述 小G养了很多狗。 小G一共有 n n n\times n nn 条狗,在一个矩阵上。小G想让狗狗交朋友,一条狗狗最多只能交一个…...
GEO生信数据挖掘(七)差异基因分析
上节,我们使用结核病基因数据,做了一个数据预处理的实操案例。例子中结核类型,包括结核,潜隐进展,对照和潜隐,四个类别。本节延续上个数据,进行了差异分析。 差异分析 计算差异指标step12 加载…...
JAVA-SpringBoot入门Demo用IDEA建立helloworld
使用编辑器IDEA做SpringBoot项目最近几年比较红红,作为JAVA语言翻身的技术,用户量激增。由于java平台原来的占有率,相比net core在某些方面更有优势。 我把本次我下载完成后Maven项目的过程记录下来了,仅供参考! 安装J…...
Unity布料系统Cloth
Unity布料系统Cloth 介绍布料系统Cloth(Unity组件)组件上的一些属性布料系统的使用布料约束Select面板Paint面板Gradient Tool面板 布料碰撞布料碰撞碰撞适用 介绍 布料系统我第一次用是做人物的裙摆自然飘动,当时我用的是UnityChan这个unity官方自带的插件做的裙摆…...
漏电继电器 LLJ-630F φ100 导轨安装 分体式结构 LLJ-630H(S) AC
系列型号: LLJ-10F(S)漏电继电器LLJ-15F(S)漏电继电器LLJ-16F(S)漏电继电器 LLJ-25F(S)漏电继电器LLJ-30F(S)漏电继电器LLJ-32F(S)漏电继电器 LLJ-60F(S)漏电继电器LLJ-63F(S)漏电继电器LLJ-80F(S)漏电继电器 LLJ-100F(S)漏电继电器LLJ-120F(S)漏电继电器LLJ-125F(S…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
