Java 登录到具有ReCaptcha的站点

Java 登录到具有ReCaptcha的站点,java,android,recaptcha,Java,Android,Recaptcha,我正在制作一个android应用程序,试图通过POST请求登录一个站点。问题是这个网站不是我的,它在登录表单上有ReCaptcha 我尝试实现android SafetyNet API,使用站点自己的站点密钥发出验证请求,但通常情况下,站点ReCaptcha密钥类型未设置为“ReCaptcha android”,因此它返回错误,因此我无法使用android SafetyNet API验证自己 我想知道是否有其他方法来验证验证码站点的服务。reCaptcha存在的全部原因是为了防止自动系统爬行或与

我正在制作一个android应用程序,试图通过POST请求登录一个站点。问题是这个网站不是我的,它在登录表单上有ReCaptcha

我尝试实现android SafetyNet API,使用站点自己的站点密钥发出验证请求,但通常情况下,站点ReCaptcha密钥类型未设置为“ReCaptcha android”,因此它返回错误,因此我无法使用android SafetyNet API验证自己


我想知道是否有其他方法来验证验证码站点的服务。

reCaptcha存在的全部原因是为了防止自动系统爬行或与系统交互。因此,在这种情况下,不幸的是,它成功地阻止了您使用android应用程序登录网站

你不应该试图绕过这一点,因为这可能违反网站的TOS,并可能使你陷入一些法律麻烦。相反,寻找一个网站提供的公共API来做你需要做的事情

此外,使用站点自己的站点密钥发出验证请求通常不起作用,因为reCaptcha只接受特定域上的密钥请求


据我所知,没有可靠的方法绕过验证码。这就是为什么验证码被许多大公司广泛信任和使用的原因。

我创建了一个WebView组件,并加载了包含验证码的页面。然后我从现有的captcha中获取站点密钥,删除页面中的所有组件,并使用javascript呈现一个新的ReCaptcha元素

当用户验证captcha时,我将验证过的令牌记录到WebView控制台,以便在我的应用程序中的进一步登录POST请求中使用。我通过覆盖WebChromeClient上的OnConsolleMessage方法来获取令牌

    // assuming theres a webview component with id 'webview'
    final WebView webView = findViewById(R.id.webview);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.setBackgroundColor(Color.TRANSPARENT);
    webView.setVisibility(View.GONE);
    webView.setWebViewClient(new WebViewClient()
    {
        @Override
        public void onPageFinished(WebView view, String url)
        {
            super.onPageFinished(view, url);

            webView.loadUrl("javascript: if($('div.g-recaptcha').length)" +
                    "{" +
                    "var sitekey = $('div.g-recaptcha').attr('data-sitekey');" + // getting the site-key from existing recaptcha element
                    "$('body > *').remove(); " + // deleting all content of the page
                    "$('body').append('<div id=\"captcha\"></div>'); " + // a div to draw new recaptcha
                    "grecaptcha.render('captcha', {\n" + // render the new recaptcha element in 'captcha' div
                    "    'sitekey' : sitekey,\n" +
                    "    'callback' : function(response){console.log('captchatoken:'+response)},\n" + // log the token on callback
                    "});" +
                    "$('body').css('background-color','transparent');" + // for aesthetic purposes
                    "}");
            webView.setVisibility(View.VISIBLE); // show the webview now since captcha is ready
        }
    });
    webView.setWebChromeClient(new WebChromeClient()
    {
        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage)
        {
            String message = consoleMessage.message();
            if (message.startsWith("captchatoken:"))
            {
                String token = message.substring(13); // removing 'captchatoken:' part from console message
                // now this token can be used in a POST request for logging in
            }
            return super.onConsoleMessage(consoleMessage);
        }
    });
    webView.loadUrl(url_that_has_captcha);
}
//假设存在id为“webview”的webview组件
最终WebView WebView=findViewById(R.id.WebView);
webView.getSettings().setJavaScriptEnabled(true);
setBackgroundColor(Color.TRANSPARENT);
webView.setVisibility(View.GONE);
setWebViewClient(新的WebViewClient()
{
@凌驾
公共void onPageFinished(WebView视图,字符串url)
{
super.onPageFinished(视图、url);
loadUrl(“javascript:if($('div.g-recaptcha').length)”+
"{" +
“var sitekey=$('div.g-repactcha').attr('data-sitekey');”+//从现有的repactcha元素获取站点密钥
“$('body>*”).remove();”+//删除页面的所有内容
$('body').append(“”);“+//一个div来绘制新的recaptcha
“grecaptcha.render('captcha',{\n”+//在'captcha'div中呈现新的recaptcha元素
“sitekey”:sitekey\n+
“'callback':函数(响应){console.log('captchatoken:'+response)},\n”+//在回调时记录令牌
"});" +
“$('body').css('background-color','transparent');”+//出于美观目的
"}");
webView.setVisibility(View.VISIBLE);//现在显示webView,因为captcha已准备就绪
}
});
setWebView.WebChromeClient(新WebChromeClient()
{
@凌驾
公共布尔onConsoleMessage(ConsoleMessage ConsoleMessage)
{
字符串消息=consoleMessage.message();
if(message.startsWith(“captchatoken:))
{
String token=message.substring(13);//从控制台消息中删除“captchatoken:”部分
//现在,可以在POST请求中使用该令牌进行登录
}
返回super.onConsoleMessage(consoleMessage);
}
});
loadUrl(具有验证码的url);
}
下面是它在实际中的表现:


我认为从WebView验证验证码并从WebView登录,然后在进一步的GET、POST请求中使用其会话cookie将解决我的问题。嘿,干得好!我犯了这样的错误。未捕获错误:试图获取id为“%s”的元素,但该元素不在页面上,我正在从此insta URL获取验证码。提前感谢:)谢谢@Dnyaneshwar!我认为你的问题是Facebook不使用常规JQuery,我的代码需要常规JQuery。我在我的存储库上改进了这个解决方案,改进后的版本不需要JQuery。您可能想在查看。如果要应用此新解决方案,您需要先创建并阅读它。此外,您还需要手动将要使用此解决方案的站点的recaptcha sitekey放入该解决方案中。您可以通过访问包含recaptcha的页面,然后打开开发人员工具,找到名为g-recaptcha的div并复制其上的数据sitekey标记来获取sitekey。谢谢@yunemregl。解决方案很好:)