Maison >interface Web >js tutoriel >Comment utiliser le marionnettiste pour déchiffrer le code de vérification coulissant de JiExperience

Comment utiliser le marionnettiste pour déchiffrer le code de vérification coulissant de JiExperience

亚连
亚连original
2018-06-04 17:36:264391parcourir

Cet article présente principalement la fonction de vérification glissante de l'utilisation du marionnettiste pour cracker Jiexi. L'implémentation du code de processus de base vous est présentée de manière très détaillée. Les amis dans le besoin peuvent se référer à

Basic. Processus :

1. Ouvrez le réseau frontal et cliquez pour vous connecter.

2. Remplissez le numéro de compte et le mot de passe.

3. Cliquez sur le bouton de vérification, vérifiez en glissant et enfin connectez-vous avec succès.

Implémentation du code :

Vous pouvez payer sur github.

Le code spécifique est le suivant :

run.js

const puppeteer = require('puppeteer');
const devices = require('puppeteer/DeviceDescriptors');
const iPhone = devices['iPhone 6 Plus'];
let timeout = function (delay) {
  return new Promise((resolve, reject) => { 
   setTimeout(() => { 
     try {
      resolve(1)
     } catch (e) {
      reject(0)
     }
   }, delay);
  })
 }
 let page = null
 let btn_position = null
 let times = 0 // 执行重新滑动的次数
 const distanceError = [-10,2,3,5] // 距离误差
 async function run() {
 const browser = await puppeteer.launch({
  headless:false //这里我设置成false主要是为了让大家看到效果,设置为true就不会打开浏览器
 });
 page = await browser.newPage();
 // 1.打开前端网
 await page.emulate(iPhone);
 await page.goto('https://www.qdfuns.com/');
 await timeout(1000);
 // 2.打开登录页面
 page.click('a[data-type=login]')
 await timeout(1000);
 // 3.输入账号密码
 page.type('input[data-type=email]','你的账号')
 await timeout(500);
 page.type('input[placeholder=密码]','你的密码')
 await timeout(1000);
 // 4.点击验证
 page.click('.geetest_radar_tip')
 await timeout(1000);
 btn_position = await getBtnPosition();
 // 5.滑动
 drag(null)
 }
 /**
 * 计算按钮需要滑动的距离 
 * */ 
 async function calculateDistance() {
 const distance = await page.evaluate(() => {
 // 比较像素,找到缺口的大概位置
 function compare(document) {
  const ctx1 = document.querySelector('.geetest_canvas_fullbg'); // 完成图片
  const ctx2 = document.querySelector('.geetest_canvas_bg'); // 带缺口图片
  const pixelDifference = 30; // 像素差
  let res = []; // 保存像素差较大的x坐标
  // 对比像素
  for(let i=57;i<260;i++){
  for(let j=1;j<160;j++) {
   const imgData1 = ctx1.getContext("2d").getImageData(1*i,1*j,1,1)
   const imgData2 = ctx2.getContext("2d").getImageData(1*i,1*j,1,1)
   const data1 = imgData1.data;
   const data2 = imgData2.data;
   const res1=Math.abs(data1[0]-data2[0]);
   const res2=Math.abs(data1[1]-data2[1]);
   const res3=Math.abs(data1[2]-data2[2]);
    if(!(res1 < pixelDifference && res2 < pixelDifference && res3 < pixelDifference)) {
    if(!res.includes(i)) {
     res.push(i);
    }
    } 
  }
  }
  // 返回像素差最大值跟最小值,经过调试最小值往左小7像素,最大值往左54像素
  return {min:res[0]-7,max:res[res.length-1]-54}
 }
 return compare(document)
 })
 return distance;
 }
 /**
 * 计算滑块位置
 */
 async function getBtnPosition() {
 const btn_position = await page.evaluate(() => {
 const {clientWidth,clientHeight} = document.querySelector(&#39;.geetest_popup_ghost&#39;)
 return {btn_left:clientWidth/2-104,btn_top:clientHeight/2+59}
 })
 return btn_position;
 }
 /**
 * 尝试滑动按钮
 * @param distance 滑动距离
 * */ 
 async function tryValidation(distance) {
 //将距离拆分成两段,模拟正常人的行为
 const distance1 = distance - 10
 const distance2 = 10
 page.mouse.click(btn_position.btn_left,btn_position.btn_top,{delay:2000})
 page.mouse.down(btn_position.btn_left,btn_position.btn_top)
 page.mouse.move(btn_position.btn_left+distance1,btn_position.btn_top,{steps:30})
 await timeout(800);
 page.mouse.move(btn_position.btn_left+distance1+distance2,btn_position.btn_top,{steps:20})
 await timeout(800);
 page.mouse.up()
 await timeout(4000);
 // 判断是否验证成功
 const isSuccess = await page.evaluate(() => {
 return document.querySelector(&#39;.geetest_success_radar_tip_content&#39;) && document.querySelector(&#39;.geetest_success_radar_tip_content&#39;).innerHTML
 })
 await timeout(1000);
 // 判断是否需要重新计算距离
 const reDistance = await page.evaluate(() => {
 return document.querySelector(&#39;.geetest_result_content&#39;) && document.querySelector(&#39;.geetest_result_content&#39;).innerHTML
 })
 await timeout(1000);
 return {isSuccess:isSuccess===&#39;验证成功&#39;,reDistance:reDistance.includes(&#39;怪物吃了拼图&#39;)}
 }
 /**
 * 拖动滑块
 * @param distance 滑动距离
 * */ 
 async function drag(distance) {
 distance = distance || await calculateDistance();
 const result = await tryValidation(distance.min)
 if(result.isSuccess) {
 await timeout(1000);
 //登录
 console.log(&#39;验证成功&#39;)
 page.click(&#39;#modal-member-login button&#39;)
 }else if(result.reDistance) {
 console.log(&#39;重新计算滑距离录,重新滑动&#39;)
 times = 0
 await drag(null)
 } else {
 if(distanceError[times]){
  times ++
  console.log(&#39;重新滑动&#39;)
  await drag({min:distance.max,max:distance.max+distanceError[times]})
 } else {
  console.log(&#39;滑动失败&#39;)
  times = 0
  run()
 }
 }
 }
 run()
package.json
{
 "name": "demo",
 "version": "1.0.0",
 "dependencies": {
 "puppeteer": "^1.0.0"
 }
}

Exécuter

1. Enregistrez ces deux fichiers dans le dossier et basculez le terminal sur le chemin actuel

2. -fin du compte réseau et du mot de passe

4. Exécution du nœud

DémoLa démo suivante peut être divisée en quatre étapes. :

1. Ouvrez la page de connexion et saisissez le mot de passe du compte que vous avez écrit à l'avance.

2. Lorsque vous faites glisser le curseur pour la première fois, le message "Été mangé par un monstre" s'affiche, de sorte que la distance d'écart de la nouvelle image est recalculée.

3. Deuxièmement, le troisième glisser indique "Pas combiné correctement", alors faites glisser à nouveau.

4. Vérification réussie, connectez-vous.

(Veuillez placer la souris sur le gif pour voir l'effet de démonstration, ou faites-le glisser vers une nouvelle fenêtre pour ouvrir le gif)

Instructions1. Il existe trois canevas pour la vérification glissante, dont seuls ceux portant les noms de classe « geetest_canvas_fullbg » et « geetest_canvas_bg » sont requis pour la comparaison des différences de pixels. ps : La première est une image complète, et la seconde est une image entaillée.

2. Chaque image avec une encoche a une ombre trompeuse, donc lorsque l'on compare la différence de pixels, les distances calculées sont respectivement une ombre et une encoche trompeuses. Par conséquent, pour la valeur de la distance de glissement, je prends '{min:res[0]-7,max:res[res.length-1]-54}'. Lorsque l'encoche est à gauche de l'ombre trompeuse, la valeur min (distance minimale) est la distance de glissement, sinon elle est max (distance maximale) moins la largeur du curseur.

3. Les résultats glissants sont divisés en trois situations : vérification réussie, mangée et échouée. "Manger" demandera à nouveau l'image, donc la distance est recalculée avant le glissement ; "Échec" sera re-swipé après 4 exécutions, l'ensemble du processus sera réexécuté.

Ce qui précède est ce que j'ai compilé pour vous. J'espère que cela vous sera utile à l'avenir.

Articles connexes :

Comment résoudre le problème de l'échec du glissement des données de chargement dynamique dans swiper ?


Des questions à ce sujet dans les fonctions fléchées ES6 ?


Quelles sont les façons d'utiliser echarts3.0 adaptatif dans vue ?


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn