puppeteer + socket.io 模拟登录并切换账号
什么是puppeteer?
puppeteer 可以用来干什么?
puppeteer 可以帮我们做很多事情,比如:UI自动化测试,性能分析等。
puppeteer 模拟登录我遇到的几个问题,以及如何解决的?
- 我想要不停的切换登录信息,我要复用我的chrome, 所以我要存下我的 websocketUrl
- 我要复用socketUrl, 我有一个主脚本main.js 和一个传入用户参数的脚本b.js , 我需要把我的账号信息传递给main.js
- 所以这就变成了:
- 1.我要在脚本a.js 与脚本main.js 之间传递我的用户名和密码参数
- 2.我的main.js在发现有a.js 这种用户脚本连上时,需要监听到,并且把它连上之前的websocketUrl
- 3.iframe 中加载登录组件资源的超时处理
- 4.被记住的用户名如何先清空再输入内容
- 结合1与2 我们想到使用socket.io
例子1: 基础模拟登录,不带socket.io (无滑动验证码)
const puppeteer = require('puppeteer');
async function login() {
let index = 0;
const browser = await puppeteer.launch({
headless: false,
});
page = await browser.newPage();
await page.goto('https://www.kaola.com/login.html');
await page.click('div[class="name head2 j-tag"]');
const frame = await page.frames().find(f => {
index = (f.name().indexOf('x-URS-iframe') !== -1) ? (index + 1) : index;
if (index === 2) {
return f; // 这里这么写是因为页面上第二个iframe 才是邮箱登录
}
});
const email = await frame.waitForSelector('input[data-type="email"]');
// 注意这里用waitForSelector 方法参考了这个issue: Any way to check iframe loaded successfully?? https://github.com/GoogleChrome/puppeteer/issues/1361
await email.click();
await email.type(process.argv[2]); // 第二个参数:用户名
const pass = await frame.$('input[class="j-inputtext dlpwd"]');
await pass.click();
await pass.type(process.argv[3]); // 第三个参数:密码
const loginBtn = await frame.$('#dologin');
loginBtn.click();
}
login()
.catch((err) => {
console.log(err);
});
例子2: 模拟登录,有socket.io (无滑动验证码)
// server.js
const Koa = require('Koa');
const app = new Koa();
const server = require('http').createServer(app.callback());
const io = require('socket.io')(server);
const puppeteer = require('puppeteer');
let wsUrl;
async function openBrowser() {
const browser = await puppeteer.launch({
headless: false,
});
const page = await browser.newPage();
wsUrl = await browser.wsEndpoint();// websocket url
}
async function login(account, password, url) {
puppeteer.connect({"browserWSEndpoint": wsUrl})
.then(async browser => {
const pageList = await browser.pages();
const page = pageList[pageList.length - 1];
let count = 500;
let frame;
let email;
await page.goto('https://m.kaola.com/login.html', {
waitUntil: 'networkidle2',
timeout: 3000000,
});
await page.setDefaultNavigationTimeout(10000000);
await page.click('li[class="email"]');
await page.waitFor(3000); // 先3s 如果不行 不断查找直到ok
frame = await page.frames().find(f => {
return f && (f.url().indexOf('index_dl.html') !== -1);
});
while(!email) {
// 注意这里用waitForSelector 方法参考了这个issue: Any way to check iframe loaded successfully?? https://github.com/GoogleChrome/puppeteer/issues/1361
email = await frame.$('input[data-type="email"]');
}
await email.focus();
await frame.$eval('input[data-type="email"]', input => {
// 如果input 文本框中有默认的邮箱地址,则清除
if(input.value) {
debugger;
input.value = '';
}
});
await email.type(account); // 第二个参数:用户名
const pass = await frame.$('input[class="j-inputtext dlpwd"]');
await pass.click();
await pass.type(password); // 第三个参数:密码
const loginBtn = await frame.$('#dologin');
await page.waitFor(3000);
await loginBtn.click();
});
}
io.on('connection', function (socket) {
console.log('connection');
socket.on('userInfo', function (data) {
const account = data.account;
const pass = data.pass;
const url = data.url;
login(account, pass, url);
});
});
server.listen(3000, '127.0.0.1');
openBrowser();
// client.js
var socket = require('socket.io-client')('http://127.0.0.1:3000');
socket.on('connect', () => {
socket.emit('userInfo', {
account: process.argv[2],
pass: process.argv[3],
url: process.argv[4],
});
});
例子3: 模拟登录 (有滑动验证码)
如果遇到有验证码的情况,我们需要使用一个叫resemble.js的库,它可以帮助我们进行图片的diff相关的操作。主要参考了下面这2篇文章, 感觉非常的赞 https://blog.oldj.net/2017/11/01/captcha-trick/ https://juejin.im/post/5a902e76f265da4e7832b2fb
拓展
基于例子2可以再集合Electron 再写点,后面会补充上来...
参考资料: 1.利用UI自动化破解滑动验证码 https://juejin.im/post/5a902e76f265da4e7832b2fb 2.使用 Node.js 模拟滑动验证码操作 https://blog.oldj.net/2017/11/01/captcha-trick/ 3.无头浏览器Puppeteer初探傀儡师 https://zhuanlan.zhihu.com/p/30203613 4.大前端神器安利之 Puppeteer https://juejin.im/entry/5a3aa0e86fb9a045076fd385 5.chrome devtools protocol https://www.wangshaoxing.com/blog/2017-08-24-chrome-devtools-protocol.html 6.puppeteer 中文api https://zhaoqize.github.io/puppeteer-api-zh_CN/#/?id=%E6%A6%82%E8%BF%B0 7.https://stackoverflow.com/questions/51039569/puppeteer-chrome-get-active-visible-tab
hello,如果用puppteer 登陆带有验证码的有什么方案,用阿里的函数运算,获取到验证码后再访问原来那个连接就不一样了
hello,如果用puppteer 登陆带有验证码的有什么方案,用阿里的函数运算,获取到验证码后再访问原来那个连接就不一样了
如果是滑动验证码:用这个库:https://github.com/HuddleEng/Resemble.js 可以通过比对出一张完整图片,和待拼图的图片之间的差异,获取到坑位信息,然后再利用puppteer模拟滑动