欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java selenium處理極驗(yàn)滑動(dòng)驗(yàn)證碼示例

 更新時(shí)間:2017年10月18日 14:46:13   作者:5432  
本篇文章主要介紹了Java selenium處理極驗(yàn)滑動(dòng)驗(yàn)證碼示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

要爬取一個(gè)網(wǎng)站遇到了極驗(yàn)的驗(yàn)證碼,這周都在想著怎么破解這個(gè),網(wǎng)上搜了好多知乎上看到有人問了這問題,我按照這思路去大概實(shí)現(xiàn)了一下。

1.使用htmlunit(這種方式我沒成功,模擬鼠標(biāo)拖拽后軌跡沒生成,可以跳過)

我用的是java,我首先先想到了用直接用htmlunit,我做了點(diǎn)初始化

private void initWebClient() {
    if (webClient != null) {
      return;
    }
    webClient = new WebClient(BrowserVersion.FIREFOX_24);
     webClient.getOptions().setProxyConfig(new ProxyConfig("127.0.0.1",8888));
    webClient.getOptions().setActiveXNative(true);
    webClient.getOptions().setUseInsecureSSL(true); // 配置證書
    webClient.getOptions().setJavaScriptEnabled(true);
    webClient.getOptions().setCssEnabled(true);
    webClient.setCssErrorHandler(new SilentCssErrorHandler());
    webClient.getOptions().setThrowExceptionOnScriptError(false);
    webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
    CookieManager cookieManager = new CookieManager();
    List<org.apache.http.cookie.Cookie> httpCookies = client.getCookies();//其方式獲取的cookie
    for (org.apache.http.cookie.Cookie cookie : httpCookies) {
      cookieManager.addCookie(new com.gargoylesoftware.htmlunit.util.Cookie(cookie));
    }
    webClient.setCookieManager(cookieManager);
  }

初始化代理,cookie..然后就能正常調(diào)用了

HtmlPage page = webClient.getPage("http://www.qixin.com/login");//企信寶
gePageInfor(page);

下面就是我獲取圖片,還原圖片并且模擬拖拽,(這里我覺得是有些問題的,可能是拖拽我模擬的不對(duì)導(dǎo)致觸發(fā)的js并沒有生成正確的軌跡,還請(qǐng)大家?guī)兔纯茨睦镥e(cuò)了)

private void gePageInfor(HtmlPage page) {
    String[] img_slice={"div", "class", "gt_cut_fullbg_slice"};
    String[] img_bg_slice={"div", "class", "gt_cut_bg_slice"};
    HtmlDivision div = (HtmlDivision) page.getElementById("captcha");
    int deCAPTCHA = 0;
    try {
      byte[] img_slice_binary = client.get(getImgUrl(img_slice, div, true)).getBinary();//獲取圖片byte
      byte[] img_bg_slice_binary = client.get(getImgUrl(img_bg_slice, div, false)).getBinary();
      //獲取還原后的圖片
      BufferedImage geetestImg = ImgTest.getGeetestImg(img_slice_binary, ImgTest.imgArray);
      BufferedImage geetestImg2 = ImgTest.getGeetestImg(img_bg_slice_binary, ImgTest.imgArray);
      //獲得圖片移動(dòng)位置(目前還有問題,需改用第三方圖片識(shí)別)
      deCAPTCHA =ImgTest.deCAPTCHA(geetestImg,geetestImg2);
      System.out.println(deCAPTCHA);
    } catch (IOException | FetchException e) {
      e.printStackTrace();
    }
    HtmlDivision div_slider_knob = get_div_slider_knob(page,"gt_slider_knob gt_show");//獲取要移動(dòng)div
    HtmlPage mouseOver = (HtmlPage) div_slider_knob.mouseOver();
    HtmlPage mouseDownPage = (HtmlPage)div_slider_knob.mouseDown();
    div_slider_knob = get_div_slider_knob(mouseDownPage,"gt_slider_knob gt_show moving");
    mouseMoveX(deCAPTCHA, div_slider_knob, mouseDownPage);
    HtmlPage newPage =(HtmlPage)div_slider_knob.mouseOver();
//    newPage =(HtmlPage)div_slider_knob.mouseDown();
    System.out.println(newPage.asXml());
    div = (HtmlDivision)newPage.getElementById("captcha");
    HtmlElement htmlElement = div.getElementsByAttribute("div", "class", "gt_slice gt_show moving").get(0);
    System.out.println(htmlElement);
    newPage =(HtmlPage)div_slider_knob.mouseUp();//觸發(fā)js,軌跡沒有生成
    System.out.println("---------------");
    System.out.println(newPage.asXml());    
    if (newPage.getElementById("captcha")!=null) {//錯(cuò)誤重試
      //gePageInfor(newPage);
    }
  }

  private void mouseMoveX(int deCAPTCHA, HtmlDivision div_slider_knob, HtmlPage mouseDown) {
    MouseEvent mouseEvent = new MouseEvent(div_slider_knob, MouseEvent.TYPE_MOUSE_MOVE, false, false, false, MouseEvent.BUTTON_LEFT);
    mouseEvent.setClientX( mouseEvent.getClientX()+((deCAPTCHA!=0)?deCAPTCHA:99));  //移動(dòng)x坐標(biāo)
    ScriptResult scriptResult = mouseDown.getDocumentElement().fireEvent(mouseEvent);
  }
  private HtmlDivision get_div_slider_knob(HtmlPage page,String classString) {
    return (HtmlDivision)(((HtmlDivision) page.getElementById("captcha")).getElementsByAttribute("div", "class", classString).get(0));
  }

  private String getImgUrl(String[] img_slice, HtmlDivision div, boolean isNeedCheckPostion) {
    String url ="";
    int[] postion = new int[2];
    boolean empty = div.getElementsByAttribute(img_slice[0],img_slice[1],img_slice[2]).isEmpty();
    if (div.hasChildNodes() && !empty) {
      List<HtmlElement> elementsByAttribute = div.getElementsByAttribute(img_slice[0],img_slice[1],img_slice[2]);  
      for(int i = 0;i<elementsByAttribute.size();i++){
        HtmlDivision div_img = (HtmlDivision)elementsByAttribute.get(i);
        String style = div_img.getAttribute("style");
        String[] imge_url_position = style.split(";");
        if(StringUtils.isBlank(url)){//確認(rèn)url
          url = StringUtils.replacePattern(imge_url_position[0], ".*\\(", "").replace(")", "");
        }
        if (isNeedCheckPostion) {//確認(rèn)圖片切割postion,兩張圖切割方式一樣 background-position: -157px -58px
//          String[] positionS = StringUtils.split(StringUtils.remove(imge_url_position[1], "px").replace("-", "").replaceAll(".*:", ""), null);
          String[] positionS = StringUtils.split(StringUtils.removePattern(imge_url_position[1], "[^\\d+ \\s]"),null);
          postion[0] = Integer.parseInt(positionS[0]);
          postion[1] = Integer.parseInt(positionS[1]);
          int[] is = ImgTest.imgArray[i];
          if (is[0]!=postion[0]||is[1]!=postion[1]) {
            logger.debug("更新分割postion");
            ImgTest.imgArray[i] = postion;
          }
          System.out.println(ImgTest.imgArray);
          isNeedCheckPostion= false;
        }
      }
    }
    return url;
  }

對(duì)比圖片獲取位移方法(deCAPTCHA)是錯(cuò)的我就不放代碼了,下面是其中還原圖片用的方法,目前是其實(shí)審查元素后你就明白怎么還原這個(gè)圖片了,這里是每次讀的10px,58px 

public static BufferedImage getGeetestImg(byte[] binary, int[][] imgArray) throws IOException {
    BufferedImage img = ImageIO.read(new ByteArrayInputStream(binary));
    List<BufferedImage> list = new ArrayList<>();
    for (int i=0;i< imgArray.length;i++) {  
      BufferedImage subimage = img.getSubimage(imgArray[i][0], imgArray[i][1], 10, 58);
      list.add(subimage);
//      ImageIO.write(subimage, "jpg", new File("d:\\image\\imgs"+i+".jpg"));
    }
    BufferedImage mergeImageUp = null;
    BufferedImage mergeImageDown = null;
    int mid = list.size()>>>1;
    for (int i = 0; i <mid-1 ; i++) {
      mergeImageUp = mergeImage(mergeImageUp==null?list.get(i):mergeImageUp, list.get(i+1), true);        
    }
    for(int i = mid;i<list.size()-1;i++){
      mergeImageDown = mergeImage(mergeImageDown==null?list.get(i):mergeImageDown,list.get(i+1), true);
    }
    img = mergeImage(mergeImageUp, mergeImageDown, false);
    return img;
  }
   public static BufferedImage mergeImage(BufferedImage img1,
        BufferedImage img2, boolean isHorizontal) throws IOException {
      int w1 = img1.getWidth();
      int h1 = img1.getHeight();
      int w2 = img2.getWidth();
      int h2 = img2.getHeight();
      // 從圖片中讀取RGB
      int[] ImageArrayOne = new int[w1 * h1];
      ImageArrayOne = img1.getRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 逐行掃描圖像中各個(gè)像素的RGB到數(shù)組中
      int[] ImageArrayTwo = new int[w2 * h2];
      ImageArrayTwo = img2.getRGB(0, 0, w2, h2, ImageArrayTwo, 0, w2);

      // 生成新圖片
      BufferedImage DestImage = null;
      if (isHorizontal) { // 水平方向合并
        DestImage = new BufferedImage(w1+w2, h1, BufferedImage.TYPE_INT_RGB);
        DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 設(shè)置上半部分或左半部分的RGB
        DestImage.setRGB(w1, 0, w2, h2, ImageArrayTwo, 0, w2);
      } else { // 垂直方向合并
        DestImage = new BufferedImage(w1, h1 + h2,
            BufferedImage.TYPE_INT_RGB);
        DestImage.setRGB(0, 0, w1, h1, ImageArrayOne, 0, w1); // 設(shè)置上半部分或左半部分的RGB
        DestImage.setRGB(0, h1, w2, h2, ImageArrayTwo, 0, w2); // 設(shè)置下半部分的RGB
      }

      return DestImage;
    }

2.使用selenium

后來我想著是我模擬鼠標(biāo)這個(gè)動(dòng)作哪里有問題,我就又找到了selenium(2.42.2),他也能操作htmlunit關(guān)鍵他的鼠標(biāo)動(dòng)作好像封裝比較完全

但是我嘗試了以后發(fā)現(xiàn)了這個(gè),HtmlUnitMouse這個(gè)動(dòng)作沒有實(shí)現(xiàn)

 public void mouseMove(Coordinates where, long xOffset, long yOffset) {
  throw new UnsupportedOperationException("Moving to arbitrary X,Y coordinates not supported.");
 }

好吧,于是調(diào)用chrome吧

System.setProperty("webdriver.chrome.driver","C:\\chromedriver.exe");
    Proxy proxy = new Proxy(); 
    //設(shè)置代理服務(wù)器地址 
    proxy.setHttpProxy("127.0.0.1:8888"); 
//    DesiredCapabilities capabilities = DesiredCapabilities.htmlUnitWithJs();
    DesiredCapabilities capabilities = DesiredCapabilities.chrome(); 
    capabilities.setCapability(CapabilityType.PROXY, proxy);
//    final WebDriver driver = new HtmlUnitDriver(capabilities);   
    WebDriver driver = new ChromeDriver(capabilities);
    driver.get("http://www.qixin.com/login");
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
     checkPage(driver,"return $('.gt_cut_fullbg_slice');");
    // 獲取 網(wǎng)頁的 title
    System.out.println("1 Page title is: " + driver.getTitle());
    // 通過 id 找到 input 的 DOM
    String pageSource = driver.getPageSource();
    System.out.println(pageSource);
    org.openqa.selenium.JavascriptExecutor executor = (org.openqa.selenium.JavascriptExecutor)driver;
    boolean equals = executor.executeScript("return document.readyState").equals("complete");
    int moveX =99;//移動(dòng)位置
    if (equals) {
      WebElement element = driver.findElement(By.className("gt_slider_knob"));//(".gt_slider_knob"));
      Point location = element.getLocation();
      element.getSize();
      Actions action = new Actions(driver); 
      //       action.clickAndHold().perform();// 鼠標(biāo)在當(dāng)前位置點(diǎn)擊后不釋放
//       action.clickAndHold(element).perform();// 鼠標(biāo)在 onElement 元素的位置點(diǎn)擊后不釋放
//       action.clickAndHold(element).moveByOffset(location.x+99,location.y).release().perform(); //選中source元素->拖放到(xOffset,yOffset)位置->釋放左鍵
       action.dragAndDropBy(element, location.x+moveX,location.y).perform();
//      action.dragAndDrop(element,newelement).perform();
      pageSource = driver.getPageSource();
    }
    //更新cookie
    Set<org.openqa.selenium.Cookie> cookies = driver.manage().getCookies();
    Set<Cookie> cookies2 = new HashSet<>();
    for (org.openqa.selenium.Cookie cookie : cookies) {
      cookies2.add((Cookie) new Cookie(cookie.getDomain(), cookie.getName(), cookie.getValue(), cookie.getPath(), cookie.getExpiry(), true));
    }
    for (Cookie cookie : cookies2) {
      org.apache.http.cookie.Cookie httpClient = cookie.toHttpClient();
    }
    System.out.println(pageSource);

這樣提交的表單確實(shí)是有軌跡的,這里移動(dòng)位置我先寫了個(gè)固定值,可以由上面圖片還原,以及一些開源的圖片識(shí)別工具識(shí)別出位置。以上應(yīng)該就能解決這個(gè)滑動(dòng)驗(yàn)證碼了

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringSecurity OAuth2單點(diǎn)登錄和登出的實(shí)現(xiàn)

    SpringSecurity OAuth2單點(diǎn)登錄和登出的實(shí)現(xiàn)

    本文主要介紹了SpringSecurity OAuth2單點(diǎn)登錄和登出的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • java操作mongodb示例分享

    java操作mongodb示例分享

    這篇文章主要介紹了java操作mongodb示例,實(shí)現(xiàn)了簡(jiǎn)單的條件查詢和復(fù)雜的條件查詢,需要的朋友可以參考下
    2014-02-02
  • Java基礎(chǔ)之刪除文本文件中特定行的內(nèi)容

    Java基礎(chǔ)之刪除文本文件中特定行的內(nèi)容

    這篇文章主要介紹了Java基礎(chǔ)之刪除文本文件中特定行的內(nèi)容,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Springboot源碼 TargetSource解析

    Springboot源碼 TargetSource解析

    這篇文章主要介紹了Springboot源碼 TargetSource解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • java?MongoDB實(shí)現(xiàn)列表分頁查詢的示例代碼

    java?MongoDB實(shí)現(xiàn)列表分頁查詢的示例代碼

    本文主要介紹了java?MongoDB實(shí)現(xiàn)列表分頁查詢的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • SpringBoot Shiro 權(quán)限注解不起作用的解決方法

    SpringBoot Shiro 權(quán)限注解不起作用的解決方法

    本文主要介紹了SpringBoot Shiro 權(quán)限注解不起作用的解決方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • SpringBoot深入分析運(yùn)行原理與功能實(shí)現(xiàn)

    SpringBoot深入分析運(yùn)行原理與功能實(shí)現(xiàn)

    我們發(fā)現(xiàn)springBoot程序開發(fā)比spring程序編寫起來容易的多。配置簡(jiǎn)潔,依賴關(guān)系簡(jiǎn)單,啟動(dòng)運(yùn)行容易。那么結(jié)下了我們我們就要思考一下入門程序中的這些功能是怎么實(shí)現(xiàn)的
    2022-09-09
  • spring?MVC實(shí)現(xiàn)簡(jiǎn)單登錄功能

    spring?MVC實(shí)現(xiàn)簡(jiǎn)單登錄功能

    這篇文章主要為大家詳細(xì)介紹了spring?MVC實(shí)現(xiàn)簡(jiǎn)單登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • mybatis中#{}和${}的區(qū)別詳解

    mybatis中#{}和${}的區(qū)別詳解

    本文主要介紹了mybatis中#{}和${}的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • idea撤銷git?commit操作詳解

    idea撤銷git?commit操作詳解

    這篇文章主要為大家介紹了idea撤銷git?commit操作詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08

最新評(píng)論