Recently we executed the CaptchaSolutions.com service testing. CaptchaSolutions.com provides an automated online captcha solver API service (the name speaks for itself). It also includes solving google reCaptcha 2.0. So we decided to test it against this challenging captcha.
Process
First we registered there and acquired the API KEY and API SECRET (to access them go to Client’s area). Then we composed a test script (python) to query the solving service.
I used the google recaptcha demo page for the service to quest it for a g-recaptcha-response token. See below on how to find a target site ReCaptcha site-key. Site-key value is highlighted in red frame on the shot below:
Using web browser inspector (F12), find and get the data-sitekey attribute value in the g-recaptcha block. Its value is a constant for a single site unless site owners change it for security purposes.
The CaptchaSolutions API provides solutions not just for reCaptcha 2.0 but for different kinds of captcha. See the documentation for what parameters to use.
Test results
Total requests: 1111
Total tokens harvested: 870 (performance is 78% of all requests)
Time spent: 94219 seconds (more than 26 hours)
Average token harvest speed: 33 token/hour or 1 token every 110 seconds.
Max token harvest speed: 162 token/hour or 1 token every 22 seconds.
This service showed a moderate average solution rate: 1 token every 110 seconds. It’s comparable to reCaptcha token life-time (2 min), so if you want to use this service, you need to be aware of this.
In case of a token failure, the service returned the following server error message:
<h2>Request Timeout</h2>
<p>This request takes too long to process, it is timed out by the server. If it should not be timed out, please contact administrator of this web site to increase ‘Connection Timeout’.
Note: For solving reCaptcha 2.0, users have to pay 5 service tokens to be able to use this API method ($2.80 for 1000 reCaptcha solved).
Script requesting token thru API
# test token capacity within a day.
import requests, time, winsound, re
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
server_url='http://api.captchasolutions.com/solve'
payload = {"googlekey": "6Le-wvkSAAAA........exq9bi0DJ",
"pageurl": 'http://google.com/recaptcha/api2/demo',
"p": 'nocaptcha',
"key": "079212ad......ea094f1ddec",
"secret": "61e....4e"}
def alarm (duration = 1000, freq = 440):
winsound.Beep(freq, duration)
def token_post(server_url, payload, timeout = 300):
try:
r = requests.post(server_url, data = payload, timeout = timeout)
except Exception as e:
print 'type:', type(e)
print e
alarm()
return None
token = r.text.replace('<captchasolutions>', '').replace('</captchasolutions>', '').replace('<decaptcha>', '').replace('</decaptcha>', '').replace('<Response [200]>', '')
#print 'raw token:',token
error_word_stack=['Timeout', 'timeout',
'error' , 'Error',
'Server' , 'server',
'html' , 'head']
if any(word in token for word in error_word_stack):
print 'Broken token:', token
return None
token = token.replace(' ', '')
token = re.sub(r"\W", "", token)
return token
start_time = time.time()
# Start of the main loop
request_counter=0
token_counter=0
failed_token_counter=0
failed_token_limit=20
max_loops = 5000
run = True
print "Max requests to be done:",max_loops
while run:
print '\n******************'
token = token_post(server_url, payload)
request_counter += 1
if token and 'None' not in token:
token_counter += 1
failed_token_counter=0
else:
failed_token_counter += 1
if failed_token_counter >= failed_token_limit:
print failed_token_limit,' or more tokens were failed.'
alarm()
run=False
if request_counter>=max_loops:
run=False
if token:
print 'Token:', token
else:
print 'Token is empty.'
print 'Total requests:', request_counter
print 'Total tokens harvested:', token_counter
print "Time spent: --- %s seconds ---" % int(time.time() - start_time)
print 'Average token harvest speed:', int(token_counter*3600/(time.time() - start_time)), 'token/hour.'
if (time.time() - start_time)>86400:
print '*\n************ The service has worked more than 24 hours. ***********\n'
alarm()
run = False
alarm()
print '************************** End of test **************************'