爬蟲-滑動驗證碼解決方案
阿新 • • 發佈:2018-12-29
一、像這種需要點選輸入,拖動模擬人工操作,且不好抓包處理的,我們可以用模擬瀏覽器解決掉他。
如selenium +chrome/phantomJs等。
首先我們要找到兩張圖片:沒有缺口和有缺口的圖片(用於對比找到缺口位置)
獲取圖片流的方法可以用如下方法;
/** * @param file 影象地址,可以是網址或者本地路徑 * @return 返回影象流 */ public BufferedImage getImage(String file) { URL url; BufferedImage bi = null; String http = "http"; String https = "https"; String get = "GET"; try { //https if (file.trim().startsWith(https)) { url = new URL(file); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod(get); //http } else if (file.trim().startsWith(http)) { url = new URL(file); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod(get); //本地檔案 } else { url = new File(file).toURI().toURL(); } //圖片流 bi = ImageIO.read(url.openStream()); } catch (Exception e) { e.printStackTrace(); } return bi ; }
有了兩張對比圖片,我們就需要遍歷檢測圖片存在不同的位置,一般肉眼看起來同一個顏色的RGB值也可能不同,所以需要設定閾值,具體閾值需要自己測試分析,我一般會遍歷列印兩圖片缺口部分及附近畫素的RGB值來取閾值。
下面上取缺口位置的程式碼,其中我對遍歷的x,y值做了限制去除圖片邊界影響,大家可以視具體情況分析使用
/** * @param origin 原圖片流 * @param slice 有缺口圖片流 * @return 缺口偏移值 */ public int getSliceOffset(BufferedImage origin,BufferedImage slice){ int offset = 0; int xMax = 300; int yMax = 100; int xyMin = 2; //遍歷x out:for(int x =xyMin;x<=xMax;x++){ //遍歷y for(int y=xyMin;y<=yMax;y++){ //若量圖片RGB差值不在閾值範圍內,則為缺口位置,閾值需要自己定義 if(Math.abs(origin.getRGB(x,y)-slice.getRGB(x,y))>5000000){ offset = x; break out; } } } return offset; }
有了缺口位置,大家就需要找到滑塊元素,將其拖動到缺口位置,具體位置可能還需要0-5的微調,所以推薦先使用視覺化模擬瀏覽器如chromeDriver,fireFoxDriver等,之後測試驗證成功後轉為無介面瀏覽器提升效能。
拖動滑塊驗證程式碼如下:
WebDriver webDriver; //配置phantomJsDriver路徑、userAgent、是否載入圖片 System.setProperty( PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, phantomJsPath); DesiredCapabilities dc = new DesiredCapabilities(); dc.setCapability("phantomjs.page.settings.userAgent", ua); dc.setCapability("phantomjs.page.settings.loadImages","true"); webDriver = new PhantomJSDriver(dc); // 開啟網址homePage webDriver.get(homePage); /** *這裡需要大家自己找到兩張對比圖片,呼叫上面的遍歷方法返回缺口偏移值,拖動滑塊移動偏移值及誤差校正 */ Actions action =new Actions(webDriver); //引數:需要拖動的滑塊元素(Element),x偏移值,y偏移值(一般只需要x偏移值,y為0) action.dragAndDropBy(slide, offset - 7, 0).perform();
此篇文章為滑動驗證碼入門篇,暫不考慮圖片亂序以及檢測機器滑動驗證碼先加速後減速的情況。