From 975316ddb7fc0c86686d41126044624b95c19943 Mon Sep 17 00:00:00 2001 From: Andrei Date: Thu, 14 Dec 2017 23:41:13 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=20=D1=81?= =?UTF-8?q?=D0=BE=20=D1=81=D0=BA=D0=B0=D1=87=D0=B0=D0=BD=D0=BD=D1=8B=D0=BC?= =?UTF-8?q?=D0=B8=20=D0=B8=D0=B7=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=D0=BC=D0=B8=20=D0=BA=D0=B0=D0=BF=D1=87=D0=B8.=20?= =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B8=D0=BC=D0=B5=D1=80=20=D0=B4=D0=BB=D1=8F=20=D1=8D=D1=82?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE.=20+=20=D0=9D=D0=B0=D1=87=D0=B0=D1=82=D0=B0?= =?UTF-8?q?=20=D0=BF=D0=B5=D1=80=D0=B5=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B8=D1=81=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B9.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../anticaptcah_image_to_text_example.py | 28 ++++++ python3_anticaptcha/ImageToTextTask.py | 88 +++++++++++++------ python3_anticaptcha/errors.py | 23 +++++ 3 files changed, 114 insertions(+), 25 deletions(-) create mode 100644 python3_anticaptcha/errors.py diff --git a/anticaptcha_examples/anticaptcah_image_to_text_example.py b/anticaptcha_examples/anticaptcah_image_to_text_example.py index cd8b88c..0f0a45b 100644 --- a/anticaptcha_examples/anticaptcah_image_to_text_example.py +++ b/anticaptcha_examples/anticaptcah_image_to_text_example.py @@ -33,6 +33,34 @@ async def run(): print(err) +if __name__ == '__main__': + loop = asyncio.get_event_loop() + loop.run_until_complete(run()) + loop.close() + +""" +Пример работы со скачанными файлами изображений капчи +""" +# Синхронный +# папка в которой находится изображение, один из вариантов написания +captcha_file = r'D:\Python\933588.png' +# так же есть возможность передать так: +# captcha_file = 'D:\/Python\/933588.png' + +result = ImageToTextTask.ImageToTextTask(anticaptcha_key = ANTICAPTCHA_KEY).captcha_handler(captcha_file = captcha_file) +print(result) + +# Асинхронный пример + +async def run(): + try: + resolve = await ImageToTextTask.aioImageToTextTask(anticaptcha_key=ANTICAPTCHA_KEY).captcha_handler(captcha_file=captcha_file) + + print(resolve) + except Exception as err: + print(err) + + if __name__ == '__main__': loop = asyncio.get_event_loop() loop.run_until_complete(run()) diff --git a/python3_anticaptcha/ImageToTextTask.py b/python3_anticaptcha/ImageToTextTask.py index d777c7f..02638fc 100644 --- a/python3_anticaptcha/ImageToTextTask.py +++ b/python3_anticaptcha/ImageToTextTask.py @@ -8,6 +8,7 @@ import os import base64 from .config import create_task_url, get_result_url, app_key +from .errors import ParamError, DownloadError, ReadError, IdGetError class ImageToTextTask: @@ -53,7 +54,7 @@ class ImageToTextTask: Метод сохраняет файл изображения как временный и отправляет его сразу на сервер для расшифровки. :return: Возвращает ID капчи ''' - with tempfile.NamedTemporaryFile(suffix='.png') as captcha_image: + with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as captcha_image: captcha_image.write(content) # Создаём пайлоад, вводим ключ от сайта, выбираем метод ПОСТ и ждём ответа в JSON-формате self.task_payload['task'].update({"body": base64.b64encode(captcha_image.read()).decode('utf-8')}) @@ -89,33 +90,54 @@ class ImageToTextTask: os.remove(os.path.join(img_path, "im-{0}.png".format(image_hash))) return captcha_id - + + def read_captcha_image_file(self, content): + """ + Функция отвечает за чтение уже сохранённого файла + :param content: Параметр строка-путь указывающий на изображение капчи для отправки её на сервер + :return: Возвращает ID капчи + """ + try: + with open(content, 'rb') as captcha_image: + # Добавляем в пайлоад картинку и отправляем + self.task_payload['task'].update({"body": base64.b64encode(captcha_image.read()).decode('utf-8')}) + # Отправляем на антикапча изображение капчи и другие парметры, + # в результате получаем JSON ответ содержащий номер решаемой капчи + captcha_id = requests.post(create_task_url, json=self.task_payload).json() + except IOError: + raise ReadError() + + return captcha_id + + # Работа с капчёй - def captcha_handler(self, captcha_link): + def captcha_handler(self, captcha_link = None, captcha_file = None): ''' Метод получает от вас ссылку на изображение, скачивает его, отправляет изображение на сервер RuCaptcha, дожидается решения капчи и вовзращает вам результат :param captcha_link: Ссылка на изображение + :param captcha_file: Необязательный параметр, служит для открытия уже скачанных файлов изображений. :return: Возвращает весь ответ сервера JSON-строкой. ''' - - content = requests.get(captcha_link).content - - # согласно значения переданного параметра выбираем функцию для сохранения изображения - if self.save_format == 'const': - captcha_id = self.image_const_saver(content) - elif self.save_format == 'temp': - captcha_id = self.image_temp_saver(content) + if captcha_file: + captcha_id = self.read_captcha_image_file(captcha_file) + elif captcha_link: + content = requests.get(captcha_link).content + # согласно значения переданного параметра выбираем функцию для сохранения изображения + if self.save_format == 'const': + captcha_id = self.image_const_saver(content) + elif self.save_format == 'temp': + captcha_id = self.image_temp_saver(content) else: - return """Wrong 'save_format' parameter. Valid formats: 'const' or 'temp'.\n - Неправильный 'save_format' параметр. Возможные форматы: 'const' или 'temp'.""" + raise ParamError(additional_info="""Wrong 'save_format' parameter. Valid formats: 'const' or 'temp'.\n + Неправильный 'save_format' параметр. Возможные форматы: 'const' или 'temp'.""") # Проверка статуса создания задачи, если создано без ошибок - извлекаем ID задачи, иначе возвращаем ответ сервера if captcha_id['errorId'] == 0: captcha_id = captcha_id["taskId"] self.result_payload.update({"taskId": captcha_id}) else: - return captcha_id + raise IdGetError(server_answer=captcha_id) # Ожидаем решения капчи time.sleep(self.sleep_time) @@ -229,32 +251,48 @@ class aioImageToTextTask: # удаляем файл капчи os.remove(os.path.join(img_path, "im-{0}.png".format(image_hash))) return captcha_id + + async def read_captcha_image_file(self, content): + try: + with open(content, 'rb') as captcha_image: + # Добавляем в пайлоад картинку и отправляем + self.task_payload['task'].update({"body": base64.b64encode(captcha_image.read()).decode('utf-8')}) + # Отправляем на антикапча изображение капчи и другие парметры, + # в результате получаем JSON ответ содержащий номер решаемой капчи + captcha_id = requests.post(create_task_url, json=self.task_payload).json() + except IOError: + raise ReadError() + return captcha_id + # Работа с капчёй - async def captcha_handler(self, captcha_link): + async def captcha_handler(self, captcha_link = None, captcha_file = None): ''' Метод получает от вас ссылку на изображение, скачивает его, отправляет изображение на сервер RuCaptcha, дожидается решения капчи и вовзращает вам результат :param captcha_link: Ссылка на изображение :return: Возвращает весь ответ сервера JSON-строкой. ''' - - # согласно значения переданного параметра выбираем функцию для сохранения изображения - if self.save_format == 'const': - captcha_id = await self.image_const_saver(captcha_link) - elif self.save_format == 'temp': - captcha_id = await self.image_temp_saver(captcha_link) + # если был передан линк на локальный скачаный файл + if captcha_file: + captcha_id = await self.read_captcha_image_file(captcha_file) + elif captcha_link: + # согласно значения переданного параметра выбираем функцию для сохранения изображения + if self.save_format == 'const': + captcha_id = await self.image_const_saver(captcha_link) + elif self.save_format == 'temp': + captcha_id = await self.image_temp_saver(captcha_link) else: - return """Wrong 'save_format' parameter. Valid formats: 'const' or 'temp'.\n - Неправильный 'save_format' параметр. Возможные форматы: 'const' или 'temp'.""" + raise ParamError(additional_info="""Wrong 'save_format' parameter. Valid formats: 'const' or 'temp'.\n + Неправильный 'save_format' параметр. Возможные форматы: 'const' или 'temp'.""") # Проверка статуса создания задачи, если создано без ошибок - извлекаем ID задачи, иначе возвращаем ответ сервера if captcha_id['errorId'] == 0: captcha_id = captcha_id["taskId"] self.result_payload.update({"taskId": captcha_id}) else: - return captcha_id - + raise IdGetError(server_answer=captcha_id) + # Ожидаем решения капчи await asyncio.sleep(self.sleep_time) # отправляем запрос на результат решения капчи, если не решена ожидаем diff --git a/python3_anticaptcha/errors.py b/python3_anticaptcha/errors.py new file mode 100644 index 0000000..372a0f9 --- /dev/null +++ b/python3_anticaptcha/errors.py @@ -0,0 +1,23 @@ +class AntiCaptchaApiException(Exception): + pass + + +class DownloadError(AntiCaptchaApiException): + def __init__(self): + AntiCaptchaApiException.__init__(self, """\nОшибка при скачивании файла""") + + +class ReadError(AntiCaptchaApiException): + def __init__(self): + AntiCaptchaApiException.__init__(self, """\nПораждается, при проблеме во время чтения сохранённого файла.""") + + +class ParamError(AntiCaptchaApiException): + def __init__(self, additional_info = None): + AntiCaptchaApiException.__init__(self, """\nПораждается, при передаче неверного параметра.""" + + additional_info if additional_info else '\n') + +class IdGetError(AntiCaptchaApiException): + def __init__(self, server_answer): + AntiCaptchaApiException.__init__(self, """\n Пораждается при ошибке получения ID капчи от сервиса. Ответ сервера:\n + {0}""".format(server_answer)) \ No newline at end of file