博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
这其实是一个求助的文章
阅读量:6291 次
发布时间:2019-06-22

本文共 5528 字,大约阅读时间需要 18 分钟。

背景

。。。。最一开始我只是想弄个帮女朋友自动清购物车的脚本顺带尝试一下puppeteer,but噩梦开始了

第一阶段 / 尝试使用puppeteer

文档在

对我这种英语差的人实在是心累,好在api简洁明了。。。虽然有些地方还不完善,没关系干的就是盲人摸象的工作。
入门教程网上还是很多的我随便贴一个

然后是打开淘宝的基础代码(太简单了,没啥要看的)

puppeteer.launch({    headless: false}).then(async browser => {    const page = await browser.newPage();    // 设置Viewport    await page.setViewport({        width: 1366,        height: 768    });    await page.goto('https://login.taobao.com/member/login.jhtml');    console.log('进入淘宝登陆页');});复制代码

第二阶段 / 非扫码模式登陆

一开始我觉的扫码多麻烦,还要把图片弄到本地啥的,果断用账号+密码+验证码来撸,

puppeteer.launch({    headless: false}).then(async browser => {    ...这里代码就不重复了    await page.waitForSelector('#J_Quick2Static');    await page.click('#J_Quick2Static');    console.log('切换至普通模式登陆');    // 判断一下登陆账号密码是否存在,不存在就输入    loginData = Object.keys(loginData).length ? loginData : await inputLoginData();    console.log('成功获取用户账号密码,开始输入');    await sleep(1000);    const usernameInput = await page.$('input[name=TPL_username]');    await usernameInput.click();    await usernameInput.type(loginData.username, {        delay: 50    });    密码也是这样    console.log('输入完毕');    const loginButton = await page.$('#J_SubmitStatic');    await loginButton.click();    console.log('登陆成功');});复制代码
// 用户输入账号密码的函数,可以不用看const inputLoginData = async () => {    const result = {};    await readSyncByRl('输入淘宝账号: ').then((msg) => {        result.username = msg;    });    await readSyncByRl('输入淘宝密码: ').then((msg) => {        result.password = msg;    });    return result;}function readSyncByRl(tips) {    tips = tips || '> ';    return new Promise((resolve) => {        const rl = readline.createInterface({            input: process.stdin,            output: process.stdout        });        rl.question(tips, (answer) => {            rl.close();            resolve(answer.trim());        });    });}复制代码

好,这样其实是可以了。。。。但是有几个问题:

1. 输入文字时间间隔

输入文字不能太快,这个其实调整delay在一定程度上可以解决

2. 如果你的账号存在嫌疑,需要滑动验证

我一开始觉得只要拖过去就可以了= =,事实证明我太天真,网上找找看到了这,大概就是说尽量模拟人的操作。。。。然后我尝试了

await page.$('#nc_1_n1z').then(async (element) => {    const point = await element.boundingBox();    console.log('进行滑动验证');    await moveSlide(point, page);}).catch(() => {    console.log('无滑动验证码');});复制代码
// 滑动验证async function moveSlide(point, page) {    await page.waitForSelector('#nc_1_n1z', {        visible: true,    });    await sleep(1000);    // 果然高中物理都还给老师了,下面模拟一个16加速度,时长为2的滑动    const mouse = page.mouse;    const x = point.x + Math.round(Math.random() * point.width / 4) + point.width / 3;    const y = point.y + Math.round(Math.random() * point.height / 4) + point.height / 3;    await mouse.move(x, y);    await mouse.down();    await sleep(200);    for (let i = 2; i > 0; i--) {        await mouse.move(x + 16 * i ** 2, y + 0.2 * i ** 2, {            steps: 2,        });    }    for (let i = 8; i > 0; i--) {        await mouse.move(x + 64 + 32 * i, y + 0.2 * i ** 2, {            steps: 2,        });    }    await mouse.up();    // 判断验证s是否通过    let ncResult = await Promise.race([        page.waitForSelector('#nocaptcha .btn_ok', {            visible: true,        }).then(() => {            return true;        }),        page.waitForSelector('#nocaptcha', {            visible: true,        }).then(() => {            return false;        }),    ]);    // 失败重新滑动    if (!ncResult) {        await page.waitForSelector('#nocaptcha a', {            visible: true,        });        await sleep(1000);        const nocaptcha = await page.$('#nocaptcha a');        await nocaptcha.click();        await sleep(1000);        await moveSlide(point, page);    }}复制代码

本来这样有3成的概率能过。。。。但是一段时间后,我发现一直都是失败,我就人工试了试,发现我的账号只要出现滑动严重人工都不能验证通过,不然就是直接可以登陆进去(T_T)

这条路就此断绝,但是我还没有放弃

第三阶段 / 扫码模式登陆

嘛。。。扫就扫。。。

原本是想直接保存二维码到本地然后打开图片扫码

await page.waitForSelector('#J_QRCodeImg');await page.$('#J_QRCodeImg').then(async (element) => {    const point = await element.boundingBox();    await page.screenshot({        path: "code.png",        clip: point,    });});复制代码

想想太不好了,显得太傻。。。突然想到了把图片转成ascii字符图,还挺好的,就只有黑白都不用做灰度处理。

let img = new Image();var result = '';img.src = document.getElementById('J_QRCodeImg').childNodes[0].src + '?t=123';img.crossOrigin = "Anonymous";img.onload = async () => {    let canvas = document.createElement('canvas');    let canvasContext = canvas.getContext("2d");    canvasContext.drawImage(img, 0, 0);    let data = [];    for (let h = 0; h < img.height; h += 2) {        for (let w = 0; w < img.width; w += 2) {            let imgData = canvasContext.getImageData(w, h, 2, 2);            let imgDataArray = imgData.data;            data.push(imgDataArray.reduce((sum, value) => {                return sum + value;            }) / (2*2*4));        }    }    let arr = ['██', '  '];    data.forEach((item, index) => {        result += arr[Math.floor(item / 157)];        if ((index + 1) % 70 == 0) {            result += '\n';        }    })}复制代码

怎么执行呢?

executionContext这个就是exec在浏览器内部的对象

const qrcode = await executionContext.evaluate(async () => {    上文内容    // 让程序停2S防止返回空字符串    await sleep(2000);    return Promise.resolve(result);    async function sleep(delay) {        return new Promise((resolve, reject) => {            setTimeout(() => {                try {                    resolve(1)                } catch (e) {                    reject(0)                }            }, delay);        });    };});复制代码

其实乍一看效果还是不错的,就是有点大,在chrome上这个特殊字符宽高比是1:2

但是在cmd上就不是这回事了

在cmd中宽高是1:1所以

// 不适用// let arr = ['██', '  '];let arr = ['█', '  '];复制代码

这个问题其实是字符集对于这个特殊字符的定义不同,这个就很难办了。。。。。总不能让别人都用一种字体

第四阶段 / 求助

咳咳。。。大家都来想想办法,还有什么好方法,请在下面留言

转载地址:http://btcta.baihongyu.com/

你可能感兴趣的文章
Vue组建通信
查看>>
用CSS画一个带阴影的三角形
查看>>
前端Vue:函数式组件
查看>>
程鑫峰:1.26特朗.普力挺美元力挽狂澜,伦敦金行情分析
查看>>
safari下video标签无法播放视频的问题
查看>>
01 iOS中UISearchBar 如何更改背景颜色,如何去掉两条黑线
查看>>
对象的继承及对象相关内容探究
查看>>
Spring: IOC容器的实现
查看>>
Serverless五大优势,成本和规模不是最重要的,这点才是
查看>>
Nginx 极简入门教程!
查看>>
iOS BLE 开发小记[4] 如何实现 CoreBluetooth 后台运行模式
查看>>
Item 23 不要在代码中使用新的原生态类型(raw type)
查看>>
为网页添加留言功能
查看>>
JavaScript—数组(17)
查看>>
Android 密钥保护和 C/S 网络传输安全理论指南
查看>>
以太坊ERC20代币合约优化版
查看>>
Why I Began
查看>>
同一台电脑上Windows 7和Ubuntu 14.04的CPU温度和GPU温度对比
查看>>
js数组的操作
查看>>
springmvc Could not write content: No serializer
查看>>