Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 免费麻豆国产一区二区三区四区,久久国产精品视频一区,日本福利视频在线观看

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          滑塊驗證碼識別、破解-技術詳解(JAVA)

          滑塊驗證碼識別、破解-技術詳解(JAVA)

          滑塊驗證碼是目前網絡上使用最多的,也是體驗相對來說比較好的一種驗證碼。但爬蟲和反爬蟲就像矛和盾一樣的關系相互促進相互影響,互聯網技術就是在這樣的不斷碰撞中向前發展。

          結合我自己的個人工作經驗,來聊聊滑塊驗證碼,我們就拿京東登陸頁面的滑塊驗證舉例,進行詳細分解學習。

          滑塊驗證碼樣例

          目標:通過算法找到需要滑動的滑塊(下文一律叫切片區)距離背景目標區域(下文一律叫背景區)的距離,然后自動拖動完成拼接。


          一、利用Chrome-F12的開發者工具來定位滑塊驗證碼的請求地址:

          1、在google瀏覽器中打開對應的網站,進入到滑塊驗證碼頁面

          2、在驗證碼頁面按F12,進入Network區

          3、點擊驗證碼右上角的換一張(圖中標號為1),目的是捕獲驗證碼的請求地址

          4、在name區可以看到多個情況地址,找到其中的驗證碼請求地址,這里是g.html(圖中標號為2)

          5、在Headers表頭可以看到對應此鏈接地址的情況地址,以及請求方式,這里是GET請求

          (注:后期可以通過JS或者Java等模擬網站GET請求來獲取驗證碼信息)

          定位滑塊驗證碼的請求地址


          二、分析、查找"切片區"和"背景區"的對應圖片數據信息:

          1、點擊開發者工具中的Response來查看請求的返回值

          2、這里是一個JSON串格式,其中bg對應的值就是背景圖片區域的base64字符串值,patch對應的值就是切片區base64字符串值.

          切片區"和"背景區"數據信息

          3、將這些base64字符串值轉換成圖片,我們看一下背景區和切片區字符串對應的具體圖像:

          (背景區)

          (切片區)

              		//切片對應的base64String
              		String sliceImg="iVBORw0KGgoAAAANSUhEUgAAADIAAA.....";//內容太多省略,自己從瀏覽器中獲取即可
              		//背景區對應的base64String
              		String bgImg="iVBORw0KGgoAAAANSUhE....";//內容太多省略,自己從瀏覽器中獲取即可
          
                 	//背景區
              		BufferedImage biBuffer=base64StringToImg(bgImg);
              		//切片區
              		BufferedImage sliceBuffer=base64StringToImg(sliceImg);
              		
                 	//將圖片輸出到本地查看
              		ImageIO.write(biBuffer,
              				"png", new File("E:\\bgImg.png"));
              		ImageIO.write(sliceBuffer,
              				"png", new File("E:\\sliceImg.png"));


          	/**
          	 * base64字符串轉存圖片
          	 * @param base64String base64字符串
          	 * @return  BufferedImage
          	 */
             public static BufferedImage base64StringToImg(final String base64String) {
                 try {
                     BASE64Decoder decoder=new BASE64Decoder();
                     byte[] bytes=decoder.decodeBuffer(base64String);
                     ByteArrayInputStream bais=new ByteArrayInputStream(bytes);
                     return ImageIO.read(bais);
                 } catch (final IOException ioe) {
                     throw new UncheckedIOException(ioe);
                 }
             }  

          三、(重點,核心)利用orc模板匹配算法進行匹配,查找最相似區域,也就是我們的期望的坐標點:
          廢話不多說,直接上代碼:

          import static com.googlecode.javacv.cpp.opencv_core.CV_32FC1;
          import static com.googlecode.javacv.cpp.opencv_core.cvCreateMat;
          import static com.googlecode.javacv.cpp.opencv_core.cvMinMaxLoc;
          import static com.googlecode.javacv.cpp.opencv_imgproc.CV_TM_CCOEFF_NORMED;
          import static com.googlecode.javacv.cpp.opencv_imgproc.cvMatchTemplate;
          import java.awt.Color;
          import java.awt.Graphics;
          import java.awt.Rectangle;
          import java.awt.image.BufferedImage;
          import java.io.ByteArrayInputStream;
          import java.io.FileOutputStream;
          import java.io.IOException;
          import java.io.UncheckedIOException;
          import java.util.ArrayList;
          import java.util.List;
          import javax.imageio.ImageIO;
          import com.googlecode.javacv.cpp.opencv_core;
          import com.googlecode.javacv.cpp.opencv_core.CvMat;
          import com.googlecode.javacv.cpp.opencv_core.CvSize;
          import com.googlecode.javacv.cpp.opencv_core.IplImage;
          import com.googlecode.javacv.cpp.opencv_imgproc;
          import sun.misc.BASE64Decoder;
          
          public class Test {
          
          	public static void main(String[] args) throws IOException {
              //切片對應的base64String
              String sliceImg="iVBORw0KGgoAAAANSUhEUgAAADIAAA.....";//內容太多省略,自己從瀏覽器中獲取即可
              //背景區對應的base64String
              String bgImg="iVBORw0KGgoAAAANSUhE....";//內容太多省略,自己從瀏覽器中獲取即可
          
          		// 背景區
          		BufferedImage biBuffer=base64StringToImg(bgImg);
          		// 切片區
          		BufferedImage sliceBuffer=base64StringToImg(sliceImg);
          
          		// 由于切片矩形區域存在透明區域,所以預處理將透明區域變成白色,方便后面對圖片二值化處理。
          		// (重點:如果這里不對透明區域預處理,切片預處理后將只有一種顏色導致匹配失敗)
          		int white=new Color(255, 255, 255).getRGB();
          		for (int x=0; x < sliceBuffer.getWidth(); x++) {
          			for (int y=0; y < sliceBuffer.getHeight(); y++) {
          				if ((sliceBuffer.getRGB(x, y) >> 24)==0) {
          					sliceBuffer.setRGB(x, y, white);
          				}
          			}
          		}
          
          		IplImage sourceImage=IplImage.createFrom(biBuffer);
          		IplImage targetImage=IplImage.createFrom(sliceBuffer);
          		CvMat sourceMat=sourceImage.asCvMat();
          		CvMat targetMat=targetImage.asCvMat();
          
          		// 模板匹配算法,根據目標圖片在背景圖片中查找相似的區域
          		List<Rectangle> a=matchTemplateTest(sourceMat, targetMat);
          
          		// 取第一個值,也就是匹配到的最相識的區域,可以定位目標坐標
          		// 也是我們期望的坐標點
          		Rectangle rec=a.get(0);
          
          		// 下面是驗證,將識別到的區域用紅色矩形框標識出來,進行驗證看是否正確
          		Graphics g=biBuffer.getGraphics();
          
          		// 畫筆顏色
          		g.setColor(Color.RED);
          
          		// 矩形框(原點x坐標,原點y坐標,矩形的長,矩形的寬)
          		g.drawRect(rec.x, rec.y, rec.width, rec.height);
          		g.dispose();
              
              //輸出到本地,驗證區域查找是否正確
          		FileOutputStream out=new FileOutputStream("d:\\checkImage.png");
          		ImageIO.write(biBuffer, "png", out);
          	}
          	/**
          	 * 模板匹配算法,根據目標圖片在背景圖片中查找相似的區域
          	 * @param sourceMat 背景區域圖片數組矩陣
          	 * @param targetMat 切片目標區域圖片數組矩陣
          	 * @return 坐標點集合
          	 */
          	public static List<Rectangle> matchTemplateTest(CvMat sourceMat, CvMat targetMat) {
          		List<Rectangle> rtn=new ArrayList<Rectangle>();
          
              //對圖象進行單通道、二值化處理
          		CvMat source=opencv_core.cvCreateMat(sourceMat.rows(), sourceMat.cols(), opencv_core.CV_8UC1);
          		CvMat target=opencv_core.cvCreateMat(targetMat.rows(), targetMat.cols(), opencv_core.CV_8UC1);
          		opencv_imgproc.cvCvtColor(sourceMat, source, opencv_imgproc.CV_BGR2GRAY);
          		opencv_imgproc.cvCvtColor(targetMat, target, opencv_imgproc.CV_BGR2GRAY);
          
          		CvSize targetSize=target.cvSize();
          		CvSize sourceSize=source.cvSize();
          
          		CvSize resultSize=new CvSize();
          		resultSize.width(sourceSize.width() - targetSize.width() + 1);
          		resultSize.height(sourceSize.height() - targetSize.height() + 1);
          
          		CvMat result=cvCreateMat(resultSize.height(), resultSize.width(), CV_32FC1);
              
              //利用模板匹配算法進行查找
          		cvMatchTemplate(source, target, result, CV_TM_CCOEFF_NORMED);
          		opencv_core.CvPoint maxLoc=new opencv_core.CvPoint();
          		opencv_core.CvPoint minLoc=new opencv_core.CvPoint();
          		double[] minVal=new double[2];
          		double[] maxVal=new double[2];
              
              //找出圖片數據中最大值及最小值的數據
          		cvMinMaxLoc(result, minVal, maxVal, minLoc, maxLoc, null);
          		Rectangle rec=new Rectangle(maxLoc.x(), maxLoc.y(), target.cols(), target.rows());
              //將查找到的坐標按最優值順序放入數組
          		rtn.add(rec);
              
          		source.release();
          		target.release();
          		result.release();
          		opencv_core.cvReleaseMat(result);
          		opencv_core.cvReleaseMat(source);
          		opencv_core.cvReleaseMat(target);
          		source=null;
          		target=null;
          		result=null;
          		return rtn;
          	}

          我們看一下識別到的結果區域(紅色矩形標識就是有系統自動識別出來的)霸氣不霸氣:

          系統自動識別出來的區域坐標

          四、根據第三步得到的移動坐標點進行坐標移動(這太小菜了,就不大篇幅在這里啰嗦了,可以使用你知道的任何技術進行模擬坐標移動),我用autoit進行舉例;

          //autoit代碼塊
          //移動鼠標指針。
          MouseMove ( x, y [, 速度] )

          //參數說明:

          x:要移動到的目標位置的 X 坐標。

          y:要移動到的目標位置的 Y 坐標。

          速度:鼠標移動速度,可設數值范圍在 1(最快)和 100(最慢)之間。若設置速度為 0 則立即移動鼠標到指定位置。默認速度為 10。

          ue可以通過插件來實現滑動驗證碼。下面是幾種方法:

          1 使用第三方滑動驗證碼庫

          可以使用第三方的滑動驗證碼庫,例如'vue-verify-slide'、'vue-slide-verify'等,這些庫已經實現了滑動驗證碼的邏輯,我們只需要將其作為插件引入即可。

          優點:實現方便,無需自己編寫邏輯代碼。

          缺點:依賴第三方庫,如果第三方庫更新不及時或存在漏洞,會影響到整個系統。

          2 自己編寫滑動驗證碼組件

          可以自己編寫滑動驗證碼組件,實現自定義的UI和邏輯。

          優點:可以自由定制UI和邏輯。

          缺點:需要編寫大量的邏輯代碼,工作量較大。

          下面是一個自己編寫的滑動驗證碼組件的示例:

          <template>
            <div class="slider-verify">
              <div class="slider-bar" :style="{left: thumbLeft}">
                <div class="slider-thumb" @mousedown="onMouseDown"></div>
              </div>
              <div class="slider-mask"></div>
            </div>
          </template>
          
          <script>
          export default {
            data() {
              return {
                isDragging: false, // 是否正在拖動滑塊
                thumbLeft: 0, // 滑塊左邊距
                maxWidth: 280, // 滑塊最大可移動距離
                dragStartX: 0, // 開始拖動時鼠標的x坐標
                dragOffsetX: 0, // 鼠標相對于滑塊左邊緣的偏移量
              };
            },
            methods: {
              onMouseDown(e) {
                this.isDragging=true;
                this.dragStartX=e.clientX;
                this.dragOffsetX=e.offsetX;
              },
              onMouseMove(e) {
                if (this.isDragging) {
                  const distance=e.clientX - this.dragStartX;
                  const thumbLeft=Math.min(Math.max(distance - this.dragOffsetX, 0), this.maxWidth);
                  this.thumbLeft=`${thumbLeft}px`;
                }
              },
              onMouseUp(e) {
                this.isDragging=false;
                if (parseInt(this.thumbLeft)===this.maxWidth) {
                  this.$emit('success');
                } else {
                  this.thumbLeft='0px';
                }
              },
            },
            mounted() {
              window.addEventListener('mousemove', this.onMouseMove);
              window.addEventListener('mouseup', this.onMouseUp);
            },
            beforeDestroy() {
              window.removeEventListener('mousemove', this.onMouseMove);
              window.removeEventListener('mouseup', this.onMouseUp);
            },
          };
          </script>
          
          <style scoped>
          .slider-verify {
            position: relative;
            width: 300px;
            height: 40px;
            border-radius: 20px;
            overflow: hidden;
          }
          .slider-bar {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
            background-color: #eee;
            transition: all 0.3s ease-out;
          }
          .slider-thumb {
            position: absolute;
            left: 0;
            top: 50%;
          width: 40px;
          height: 40px;
          border-radius: 50%;
          background-color: #fff;
          box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
          transition: all 0.3s ease-out;
          }
          .slider-mask {
          position: absolute;
          left: 0;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: rgba(0, 0, 0, 0.05);
          border-radius: 20px;
          }
          </style>
          

          3 使用canvas實現滑動驗證碼

          可以使用canvas繪制滑動驗證碼,將滑塊拖動的距離作為驗證依據。

          優點:可以自由定制UI和邏輯,滑動效果更流暢。

          缺點:需要對canvas有一定的了解,對性能有一定的影響。

          下面是一個使用canvas實現的滑動驗證碼的示例:

          <template>
            <div class="canvas-verify">
              <canvas ref="canvas" :width="canvasWidth" :height="canvasHeight" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp"></canvas>
            </div>
          </template>
          
          <script>
          export default {
            data() {
              return {
                isDragging: false, // 是否正在拖動滑塊
                thumbLeft: 0, // 滑塊左邊距
                canvasWidth: 300, // canvas寬度
                canvasHeight: 150, // canvas高度
                maxWidth: 250, // 滑塊最大可移動距離
                dragStartX: 0, // 開始拖動時鼠標的x坐標
                dragOffsetX: 0, // 鼠標相對于滑塊左邊緣的偏移量
                canvasContext: null, // canvas context
                imagePath: '', // 背景圖路徑
              };
            },
            methods: {
              onMouseDown(e) {
                if (this.isDragging) {
                  return;
                }
                const rect=this.$refs.canvas.getBoundingClientRect();
                this.isDragging=true;
                this.dragStartX=e.clientX - rect.left;
                this.dragOffsetX=this.dragStartX - this.thumbLeft;
              },
              onMouseMove(e) {
                if (this.isDragging) {
                  const rect=this.$refs.canvas.getBoundingClientRect();
                  const distance=e.clientX - rect.left - this.dragOffsetX;
                  const thumbLeft=Math.min(Math.max(distance, 0), this.maxWidth);
                  this.thumbLeft=thumbLeft;
                  this.draw();
                }
              },
              onMouseUp(e) {
                if (this.isDragging) {
                  this.isDragging=false;
                  if (this.thumbLeft===this.maxWidth) {
                    this.$emit('success');
                  } else {
                    this.thumbLeft=0;
                    this.draw();
                  }
                }
              },
              draw() {
                this.canvasContext.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
                // 繪制背景圖
                const image=new Image();
                image.src=this.imagePath;
                image.onload=()=> {
                  this.canvasContext.drawImage(image, 0, 0, this.canvasWidth, this.canvasHeight);
                  // 繪制滑塊
                  this.canvasContext.fillStyle='#ccc';
                  this.canvasContext.fillRect(this.thumbLeft, 50, 50, 50);
                };
              },
            },
            mounted() {
              // 獲取canvas context
              this.canvasContext=this.$refs.canvas.getContext('2d');
              // 加載背景圖
              this.imagePath='https://picsum.photos/300/150/?random';
              const image=new Image();
              image.src=this.imagePath;
              image.onload=()=> {
                this.draw();
              };
            },
            beforeUnmount() {
              this.canvasContext=null;
            },
          };
          </script>
          
          <style scoped>
          .canvas-verify {
            position: relative;
          }
          </style>
          

          這個示例中,滑塊使用了一個矩形代替,顏色為灰色。使用canvas實現滑動驗證碼需要對canvas有一定的了解,同時對性能也有一定的影響。但是可以自由定制UI和邏輯,實現更靈活。

          以上是三種常見的實現滑動驗證碼的方法,每種方法都有其優點和缺點。使用CSS實現最簡單,但是不太安全;使用canvas實現最靈活,但是需要對canvas有一定的了解;使用第三方庫可以更快速地實現,但是需要依賴第三方庫。具體使用哪種方法應該根據實際情況選擇,權衡各種因素。

          本文的文字及圖片來源于網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。

          作者:卡卡叮

          PS:如有需要Python學習資料的小伙伴可以私信小編



          這篇文章主要介紹了python模擬嗶哩嗶哩滑塊登入驗證的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

          準備工具

          • pip3 install PIL
          • pip3 install opencv-python
          • pip3 install numpy

          谷歌驅動

          建議指定清華源下載速度會更快點

          使用方法 :

          pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple/opencv-python/

          谷歌驅動

          谷歌驅動下載鏈接 :http://npm.taobao.org/mirrors/chromedriver/



          本篇文章采用的是cv2的Canny邊緣檢測算法進行圖像識別匹配。

          Canny邊緣檢測算法參考鏈接:https://www.jb51.net/article/185336.htm

          具體使用的是Canny的matchTemplate方法進行模糊匹配,匹配方法用CV_TM_CCOEFF_NORMED歸一化相關系數匹配。得出的max_loc就是匹配出來的位置信息。從而達到位置的距離。

          難點

          由于圖像采用放大的效果匹配出的距離偏大,難以把真實距離,并存在誤差。

          由于嗶哩嗶哩滑塊驗證進一步采取做了措施,如果滑動時間過短,會導致驗證登入失敗。所以我這里采用變速的方法,在相同時間內滑動不同的距離。

          誤差的存在是必不可少的,有時會導致驗證失敗,這都是正常現象。

          流程

          1.實例化谷歌瀏覽器 ,并打開嗶哩嗶哩登入頁面。

          2.點擊登陸,彈出滑動驗證框。

          3.全屏截圖、后按照尺寸裁剪各兩張。

          5.模糊匹配兩張圖片,從而獲取匹配結果以及位置信息 。

          6.將位置信息與頁面上的位移距離轉化,并盡可能少的減少誤差 。

          7.變速的拖動滑塊到指定位置,從而達到模擬登入。

          效果圖

          代碼實例

          庫安裝好后,然后填寫配置區域后即可運行。

          from PIL import Image
          from time import sleep
          from selenium import webdriver
          from selenium.webdriver import ActionChains
          from selenium.webdriver.common.by import By
          from selenium.webdriver.support.ui import WebDriverWait
          from selenium.webdriver.support import expected_conditions as EC
          import cv2
          import numpy as np
          import math
          ############ 配置區域 #########
          
          zh='' #賬號
          pwd='' #密碼
           # chromedriver的路徑
          chromedriver_path="C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe"
          
          ####### end #########
          
          options=webdriver.ChromeOptions()
          options.add_argument('--no-sandbox')
          options.add_argument('--window-size=1020,720')
          # options.add_argument('--start-maximized') # 瀏覽器窗口最大化
          options.add_argument('--disable-gpu')
          options.add_argument('--hide-scrollbars')
          options.add_argument('test-type')
          options.add_experimental_option("excludeSwitches", ["ignore-certificate-errors",
                       "enable-automation"]) # 設置為開發者模式
          driver=webdriver.Chrome(options=options, executable_path=chromedriver_path)
          driver.get('https://passport.bilibili.com/login')
          
          # 登入
          def login():
           driver.find_element_by_id("login-username").send_keys(zh)
           driver.find_element_by_id("login-passwd").send_keys(pwd)
           driver.find_element_by_css_selector("#geetest-wrap > div > div.btn-box > a.btn.btn-login").click()
           print("點擊登入")
          
          # 整個圖,跟滑塊整個圖
          def screen(screenXpath):
           img=WebDriverWait(driver, 20).until(
            EC.visibility_of_element_located((By.XPATH, screenXpath))
           )
           driver.save_screenshot("allscreen.png") # 對整個瀏覽器頁面進行截圖
           left=img.location['x']+160 #往右
           top=img.location['y']+60 # 往下
           right=img.location['x'] + img.size['width']+230 # 往左
           bottom=img.location['y'] + img.size['height']+110 # 往上
           im=Image.open('allscreen.png')
           im=im.crop((left, top, right, bottom)) # 對瀏覽器截圖進行裁剪
           im.save('1.png')
           print("截圖完成1")
           screen_two(screenXpath)
           screen_th(screenXpath)
           matchImg('3.png','2.png')
          
          # 滑塊部分圖
          def screen_two(screenXpath):
           img=WebDriverWait(driver, 20).until(
            EC.visibility_of_element_located((By.XPATH, screenXpath))
           )
           left=img.location['x'] + 160
           top=img.location['y'] + 80
           right=img.location['x'] + img.size['width']-30
           bottom=img.location['y'] + img.size['height'] + 90
           im=Image.open('allscreen.png')
           im=im.crop((left, top, right, bottom)) # 對瀏覽器截圖進行裁剪
           im.save('2.png')
           print("截圖完成2")
          
          # 滑塊剩余部分圖
          def screen_th(screenXpath):
           img=WebDriverWait(driver, 20).until(
            EC.visibility_of_element_located((By.XPATH, screenXpath))
           )
           left=img.location['x'] + 220
           top=img.location['y'] + 60
           right=img.location['x'] + img.size['width']+230
           bottom=img.location['y'] + img.size['height'] +110
           im=Image.open('allscreen.png')
           im=im.crop((left, top, right, bottom)) # 對瀏覽器截圖進行裁剪
           im.save('3.png')
           print("截圖完成3")
          
          #圖形匹配
          def matchImg(imgPath1,imgPath2):
           imgs=[]
           #展示
           sou_img1=cv2.imread(imgPath1)
           sou_img2=cv2.imread(imgPath2)
           # 最小閾值100,最大閾值500
           img1=cv2.imread(imgPath1, 0)
           blur1=cv2.GaussianBlur(img1, (3, 3), 0)
           canny1=cv2.Canny(blur1, 100, 500)
           cv2.imwrite('temp1.png', canny1)
           img2=cv2.imread(imgPath2, 0)
           blur2=cv2.GaussianBlur(img2, (3, 3), 0)
           canny2=cv2.Canny(blur2, 100, 500)
           cv2.imwrite('temp2.png', canny2)
           target=cv2.imread('temp1.png')
           template=cv2.imread('temp2.png')
           # 調整大小
           target_temp=cv2.resize(sou_img1, (350, 200))
           target_temp=cv2.copyMakeBorder(target_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])
           template_temp=cv2.resize(sou_img2, (200, 200))
           template_temp=cv2.copyMakeBorder(template_temp, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])
           imgs.append(target_temp)
           imgs.append(template_temp)
           theight, twidth=template.shape[:2]
           # 匹配跟拼圖
           result=cv2.matchTemplate(target, template, cv2.TM_CCOEFF_NORMED)
           cv2.normalize( result, result, 0, 1, cv2.NORM_MINMAX, -1 )
           min_val, max_val, min_loc, max_loc=cv2.minMaxLoc(result)
           # 畫圈
           cv2.rectangle(target,max_loc,(max_loc[0]+twidth,max_loc[1]+theight),(0,0,255),2)
           target_temp_n=cv2.resize(target, (350, 200))
           target_temp_n=cv2.copyMakeBorder(target_temp_n, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[255, 255, 255])
           imgs.append(target_temp_n)
           imstack=np.hstack(imgs)
          
           cv2.imshow('windows'+str(max_loc), imstack)
           cv2.waitKey(0)
           cv2.destroyAllWindows()
          
           # 計算距離
           print(max_loc)
           dis=str(max_loc).split()[0].split('(')[1].split(',')[0]
           x_dis=int(dis)+135
           t(x_dis)
          
          
          #拖動滑塊
          def t(distances):
           draggable=driver.find_element_by_css_selector('div.geetest_slider.geetest_ready > div.geetest_slider_button')
           ActionChains(driver).click_and_hold(draggable).perform() #抓住
           print(driver.title)
           num=getNum(distances)
           sleep(3)
           for distance in range(1,int(num)):
            print('移動的步數: ',distance)
            ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()
            sleep(0.25)
           ActionChains(driver).release().perform() #松開
          
          
          # 計算步數
          def getNum(distances):
           p=1+4*distances
           x1=(-1 + math.sqrt(p)) / 2
           x2=(-1 - math.sqrt(p)) / 2
           print(x1,x2)
           if x1>=0 and x2<0:
            return x1+2
           elif(x1<0 and x2>=0):
            return x2+2
           else:
            return x1+2
          
          def main():
           login()
           sleep(5)
           screenXpath='/html/body/div[2]/div[2]/div[6]/div/div[1]/div[1]/div/a/div[1]/div/canvas[2]'
           screen(screenXpath)
           sleep(5)
          
          
          if __name__=='__main__':
           main()
          

          有能力的可以研究一下思路,然后寫出更好的解決辦法。


          主站蜘蛛池模板: 久久一区二区明星换脸| 亚洲综合一区二区精品导航| 精品国产一区二区三区免费| 无码免费一区二区三区免费播放| 在线视频亚洲一区| 亚洲视频在线一区二区三区| 亚洲国产综合无码一区二区二三区 | 日韩精品一区二区亚洲AV观看| 精品视频在线观看一区二区| 亚洲一区二区三区在线网站| 无码日韩精品一区二区三区免费 | 精品一区二区三区四区在线播放| 久久精品国产一区二区三区肥胖| 亚洲午夜电影一区二区三区| 国产成人一区二区三区免费视频 | 成人一区二区免费视频| 国产精品盗摄一区二区在线| 精品欧洲AV无码一区二区男男| 人妻AV一区二区三区精品| 中文字幕一区二区人妻| 久久99精品国产一区二区三区| 99久久精品费精品国产一区二区 | 99精品一区二区三区| 性色A码一区二区三区天美传媒| 国精产品一区二区三区糖心| 中文字幕一区二区区免| 国产在线不卡一区二区三区| 日韩欧国产精品一区综合无码| 国偷自产av一区二区三区| 熟女精品视频一区二区三区| 日韩精品无码一区二区三区| 99无码人妻一区二区三区免费| 国产精品一区二区久久| 怡红院一区二区三区| 美女视频一区二区三区| 大伊香蕉精品一区视频在线| 亚洲一区综合在线播放| 国产怡春院无码一区二区| 精品在线一区二区三区| 伊人久久精品无码av一区| 精品无码国产一区二区三区AV|