ホームページ  >  記事  >  ウェブフロントエンド  >  puppeteer を使用して JiExperience のスライディング検証コードをクラックする方法

puppeteer を使用して JiExperience のスライディング検証コードをクラックする方法

亚连
亚连オリジナル
2018-06-04 17:36:264328ブラウズ

この記事では主に、Puppeteer を使用して Jiexi をクラックするためのスライディング検証機能を紹介します。基本的なプロセス コードの実装が詳しく紹介されています。必要な方は参考にしてください。

1.フロントエンド Web サイトを開き、クリックしてログインします。 2. アカウント番号とパスワードを入力します。

3. 認証ボタンをクリックし、スライドして認証し、最後にログインに成功します。

コードの実装:

githubでチェックアウトできます。 具体的なコードは次のとおりです:

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"
 }
}

これら2つのファイルをフォルダーに保存し、ターミナルを現在のパスに切り替えます

2。 npm i3. フロントエンドネットワークのアカウントとパスワードを入力します4. ノードの実行

次のデモは 4 つのステップに分かれています:

1. ログインを開きます。のページにアクセスし、事前に記入したアカウントパスワードを入力します。

2. 初めてスライダーをドラッグすると、「モンスターに食べられました」というメッセージが表示されるので、新しい画像のギャップ距離が再計算されます。

3. 次に、3回目のドラッグ後に「正しく結合されていません」というメッセージが表示されるので、もう一度ドラッグします。 4. 認証に成功し、ログインします。 (GIF 上にマウスを置いてデモンストレーション効果を確認するか、新しいウィンドウにドラッグして GIF を開きます)

手順

1 スライド検証には 3 つのキャンバスがあります。 、そのうちクラス名のみが 'geetest_canvas_fullbg ' とピクセル差比較用の 'geetest_canvas_bg' です。 ps: 前者は全体像、後者は切り欠きのある絵です。

2. ノッチのあるすべての画像には誤解を招く影があるため、ピクセルの差を比較すると、計算された距離がそれぞれ誤解を招く影とノッチになります。したがって、スライド距離の値は、「{min:res[0]-7,max:res[res.length-1]-54}」とします。ノッチが誤解を招く影の左側にある場合、min (最小距離) の値はスライド距離になります。それ以外の場合、max (最大距離) からスライダーの幅を引いた値になります。

3. スライディングの結果は、検証成功、食べられた、失敗の 3 つの状況に分けられます。 「食べる」は画像を再リクエストするため、スライドする前に距離が再計算されます。「失敗」は 4 回実行しても失敗する場合、プロセス全体が再実行されます。

上記は私があなたのためにまとめたものです。

関連記事:

スワイパーでの動的読み込みデータのスライド失敗の問題を解決するにはどうすればよいですか?

ES6 のアロー関数に関するこれについて質問はありますか?

vueでecharts3.0adaptiveを使用する方法は何ですか?



以上がpuppeteer を使用して JiExperience のスライディング検証コードをクラックする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。