# -*- coding: utf-8 -*-
''' Работа с anti-captcha.com '''
import time
import httplib
import urllib
import re
import logging
import socket
from base64 import b64encode
"""
Для загрузки изображения на сервер необходимо:
1. Конвертировать графический образ в формат Base64
2. Методом POST отправить на http://de-captcha.com/loadcapcha.php переменные:
account - Ваш уникальный код
password - Ваш Пароль на загрузку
img - Ваше изображение в Base64
В ответе Вы можете получить:
Хэш - Хэш код загруженного изображения
[error_format] - Ошибка в формате передачи
[error_errorbalance] - Пополните свой баланс
[error_load] - Ошибка при загрузке изображения на сервер
[error_baseconnect] - Ошибка на сервере. Обратитесь к администратору
[error_accessdenied] - Неправильный уникальный код или пароль на загрузку
[error_errorbalance] - Пополните свой баланс
3. Опрашивать с определенным интервалом (любым удобным для Вас < 1 минуты) скрипт http://de-captcha.com/finger.php?hash=[хэш-код изображения]. Результат выдается массивом в формате функции serialize (PHP):
a:3:{s:4:"hash";s:3:"332";s:6:"answer";s:2:"as";s:6:"status";s:15:"[UNDEFINEDHASH]";}
Где a:3 - ассоциативный массив размерностью в три.
s:XX - строка размером XX
Приведенный код можно представить как:
array("hash"=>"332", "answer"=>"as", "status"=>"[UNDEFINEDHASH]")
Ключ "hash" - хэш-код загруженного изображения
Ключ "answer" - результат распознавания
Ключ "status" - статус распознавания:
[HANDGET] - результат получен
[UNDEFINEDHASH] - изображения с данным хэш-кодом удалено с сервера
[ERRORANSWER] - изображение распознано неверно
[DELAY] - изображение в обработке
[TIMEOUT] - превышен срок распознавания образа
"""
TIMEOUT = 60
def setup_socket(func):
def inner(*args, **kwargs):
try:
oldtimeout = socket.setdefaulttimeout(TIMEOUT)
return func(*args, **kwargs)
finally:
socket.setdefaulttimeout(oldtimeout)
return inner
def php_deserialize(data):
"""
a:3:{s:4:"hash";s:3:"332";s:6:"answer";s:2:"as";s:6:"status";s:15:"[UNDEFINEDHASH]";}
"""
re_item = re.compile('s:\d+:"([^"]*)";')
items = re_item.findall(data)
hash = dict(items[x:x + 2] for x in xrange(0, len(items), 2))
return hash
@setup_socket
def fetch_solution(hash):
logging.info('Receiving captcha solution')
time.sleep(4)
# получаем результат
res_url = 'http://de-captcha.com/finger.php?hash=%s' % hash
TIMEOUT = 60
for x in xrange(TIMEOUT):
time.sleep(1)
if not x % 5:
logging.debug('Waiting %d seconds' % (5 + x))
res = urllib.urlopen(res_url).read()
res = php_deserialize(res)
if res['status'] != '[DELAY]':
break
else:
raise IOError('Timeout! (%d seconds)' % TIMEOUT)
logging.debug('De-captcha response: %s' % res)
res = res['answer']
return res
@setup_socket
def send_captcha(username, password, rawimage, **kwargs):
logging.info('Submitting captcha.')
img = b64encode(rawimage)
post = urllib.urlencode({'account': username, 'password': password, 'img': img})
res = urllib.urlopen('http://de-captcha.com/loadcapcha.php', post).read()
if not res[0] == '[':
return res
else:
raise IOError(res)
def solve_captcha(username, password, rawimage, **kwargs):
hash = send_captcha(username, password, rawimage, **kwargs)
solution = fetch_solution(hash)
return solution