This commit is contained in:
marco
2020-08-16 10:18:28 +02:00
parent 8505158a2f
commit ae2a9d7c72
6 changed files with 167 additions and 110 deletions
@@ -1,14 +1,18 @@
from __future__ import absolute_import from __future__ import absolute_import
import requests import requests
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
from ..exceptions import ( from ..exceptions import (
reCaptchaServiceUnavailable, CaptchaServiceUnavailable,
reCaptchaAPIError, CaptchaAPIError,
reCaptchaTimeout, CaptchaTimeout,
reCaptchaParameter, CaptchaParameter,
reCaptchaBadJobID, CaptchaBadJobID,
reCaptchaReportError CaptchaReportError
) )
try: try:
@@ -19,10 +23,10 @@ except ImportError:
"https://github.com/justiniso/polling/" "https://github.com/justiniso/polling/"
) )
from . import reCaptcha from . import Captcha
class captchaSolver(reCaptcha): class captchaSolver(Captcha):
def __init__(self): def __init__(self):
super(captchaSolver, self).__init__('2captcha') super(captchaSolver, self).__init__('2captcha')
@@ -34,7 +38,7 @@ class captchaSolver(reCaptcha):
@staticmethod @staticmethod
def checkErrorStatus(response, request_type): def checkErrorStatus(response, request_type):
if response.status_code in [500, 502]: if response.status_code in [500, 502]:
raise reCaptchaServiceUnavailable('2Captcha: Server Side Error {}'.format(response.status_code)) raise CaptchaServiceUnavailable('2Captcha: Server Side Error {}'.format(response.status_code))
errors = { errors = {
'in.php': { 'in.php': {
@@ -81,7 +85,7 @@ class captchaSolver(reCaptcha):
} }
if response.json().get('status') == 0 and response.json().get('request') in errors.get(request_type): if response.json().get('status') == 0 and response.json().get('request') in errors.get(request_type):
raise reCaptchaAPIError( raise CaptchaAPIError(
'{} {}'.format( '{} {}'.format(
response.json().get('request'), response.json().get('request'),
errors.get(request_type).get(response.json().get('request')) errors.get(request_type).get(response.json().get('request'))
@@ -92,8 +96,8 @@ class captchaSolver(reCaptcha):
def reportJob(self, jobID): def reportJob(self, jobID):
if not jobID: if not jobID:
raise reCaptchaBadJobID( raise CaptchaBadJobID(
"2Captcha: Error bad job id to request reCaptcha." "2Captcha: Error bad job id to request Captcha."
) )
def _checkRequest(response): def _checkRequest(response):
@@ -123,15 +127,15 @@ class captchaSolver(reCaptcha):
if response: if response:
return True return True
else: else:
raise reCaptchaReportError( raise CaptchaReportError(
"2Captcha: Error - Failed to report bad reCaptcha solve." "2Captcha: Error - Failed to report bad Captcha solve."
) )
# ------------------------------------------------------------------------------- # # ------------------------------------------------------------------------------- #
def requestJob(self, jobID): def requestJob(self, jobID):
if not jobID: if not jobID:
raise reCaptchaBadJobID("2Captcha: Error bad job id to request reCaptcha.") raise CaptchaBadJobID("2Captcha: Error bad job id to request Captcha.")
def _checkRequest(response): def _checkRequest(response):
if response.ok and response.json().get('status') == 1: if response.ok and response.json().get('status') == 1:
@@ -160,8 +164,8 @@ class captchaSolver(reCaptcha):
if response: if response:
return response.json().get('request') return response.json().get('request')
else: else:
raise reCaptchaTimeout( raise CaptchaTimeout(
"2Captcha: Error failed to solve reCaptcha." "2Captcha: Error failed to solve Captcha."
) )
# ------------------------------------------------------------------------------- # # ------------------------------------------------------------------------------- #
@@ -192,6 +196,14 @@ class captchaSolver(reCaptcha):
} }
) )
if self.proxy:
data.update(
{
'proxy': self.proxy,
'proxytype': self.proxyType
}
)
response = polling.poll( response = polling.poll(
lambda: self.session.post( lambda: self.session.post(
'{}/in.php'.format(self.host), '{}/in.php'.format(self.host),
@@ -207,24 +219,35 @@ class captchaSolver(reCaptcha):
if response: if response:
return response.json().get('request') return response.json().get('request')
else: else:
raise reCaptchaBadJobID( raise CaptchaBadJobID(
'2Captcha: Error no job id was returned.' '2Captcha: Error no job id was returned.'
) )
# ------------------------------------------------------------------------------- # # ------------------------------------------------------------------------------- #
def getCaptchaAnswer(self, captchaType, url, siteKey, reCaptchaParams): def getCaptchaAnswer(self, captchaType, url, siteKey, captchaParams):
jobID = None jobID = None
if not reCaptchaParams.get('api_key'): if not captchaParams.get('api_key'):
raise reCaptchaParameter( raise CaptchaParameter(
"2Captcha: Missing api_key parameter." "2Captcha: Missing api_key parameter."
) )
self.api_key = reCaptchaParams.get('api_key') self.api_key = captchaParams.get('api_key')
if reCaptchaParams.get('proxy'): if captchaParams.get('proxy') and not captchaParams.get('no_proxy'):
self.session.proxies = reCaptchaParams.get('proxies') hostParsed = urlparse(captchaParams.get('proxy', {}).get('https'))
if not hostParsed.scheme:
raise CaptchaParameter('Cannot parse proxy correctly, bad scheme')
if not hostParsed.netloc:
raise CaptchaParameter('Cannot parse proxy correctly, bad netloc')
self.proxyType = hostParsed.scheme
self.proxy = hostParsed.netloc
else:
self.proxy = None
try: try:
jobID = self.requestSolve(captchaType, url, siteKey) jobID = self.requestSolve(captchaType, url, siteKey)
@@ -234,12 +257,12 @@ class captchaSolver(reCaptcha):
if jobID: if jobID:
self.reportJob(jobID) self.reportJob(jobID)
except polling.TimeoutException: except polling.TimeoutException:
raise reCaptchaTimeout( raise CaptchaTimeout(
"2Captcha: reCaptcha solve took to long and also failed reporting the job the job id {}.".format(jobID) "2Captcha: Captcha solve took to long and also failed reporting the job the job id {}.".format(jobID)
) )
raise reCaptchaTimeout( raise CaptchaTimeout(
"2Captcha: reCaptcha solve took to long to execute job id {}, aborting.".format(jobID) "2Captcha: Captcha solve took to long to execute job id {}, aborting.".format(jobID)
) )
@@ -14,7 +14,7 @@ captchaSolvers = {}
# ------------------------------------------------------------------------------- # # ------------------------------------------------------------------------------- #
class reCaptcha(ABC): class Captcha(ABC):
@abc.abstractmethod @abc.abstractmethod
def __init__(self, name): def __init__(self, name):
captchaSolvers[name] = self captchaSolvers[name] = self
@@ -26,10 +26,10 @@ class reCaptcha(ABC):
if name not in captchaSolvers: if name not in captchaSolvers:
try: try:
__import__('{}.{}'.format(cls.__module__, name)) __import__('{}.{}'.format(cls.__module__, name))
if not isinstance(captchaSolvers.get(name), reCaptcha): if not isinstance(captchaSolvers.get(name), Captcha):
raise ImportError('The anti reCaptcha provider was not initialized.') raise ImportError('The anti captcha provider was not initialized.')
except ImportError: except ImportError:
logging.error("Unable to load {} anti reCaptcha provider".format(name)) logging.error("Unable to load {} anti captcha provider".format(name))
raise raise
return captchaSolvers[name] return captchaSolvers[name]
@@ -37,10 +37,10 @@ class reCaptcha(ABC):
# ------------------------------------------------------------------------------- # # ------------------------------------------------------------------------------- #
@abc.abstractmethod @abc.abstractmethod
def getCaptchaAnswer(self, captchaType, url, siteKey, reCaptchaParams): def getCaptchaAnswer(self, captchaType, url, siteKey, captchaParams):
pass pass
# ------------------------------------------------------------------------------- # # ------------------------------------------------------------------------------- #
def solveCaptcha(self, captchaType, url, siteKey, reCaptchaParams): def solveCaptcha(self, captchaType, url, siteKey, captchaParams):
return self.getCaptchaAnswer(captchaType, url, siteKey, reCaptchaParams) return self.getCaptchaAnswer(captchaType, url, siteKey, captchaParams)
+109
View File
@@ -0,0 +1,109 @@
from __future__ import absolute_import
from ..exceptions import (
CaptchaParameter,
CaptchaTimeout,
CaptchaAPIError
)
try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
try:
from python_anticaptcha import (
AnticaptchaClient,
NoCaptchaTaskProxylessTask,
HCaptchaTaskProxyless,
NoCaptchaTask,
HCaptchaTask,
AnticaptchaException
)
except ImportError:
raise ImportError(
"Please install/upgrade the python module 'python_anticaptcha' via "
"pip install python-anticaptcha or https://github.com/ad-m/python-anticaptcha/"
)
import sys
from . import Captcha
class captchaSolver(Captcha):
def __init__(self):
if sys.modules['python_anticaptcha'].__version__ < '0.6':
raise ImportError(
"Please upgrade the python module 'python_anticaptcha' via "
"pip install -U python-anticaptcha or https://github.com/ad-m/python-anticaptcha/"
)
super(captchaSolver, self).__init__('anticaptcha')
# ------------------------------------------------------------------------------- #
def parseProxy(self, url, user_agent):
parsed = urlparse(url)
return dict(
proxy_type=parsed.scheme,
proxy_address=parsed.hostname,
proxy_port=parsed.port,
proxy_login=parsed.username,
proxy_password=parsed.password,
user_agent=user_agent
)
# ------------------------------------------------------------------------------- #
def getCaptchaAnswer(self, captchaType, url, siteKey, captchaParams):
if not captchaParams.get('api_key'):
raise CaptchaParameter("anticaptcha: Missing api_key parameter.")
client = AnticaptchaClient(captchaParams.get('api_key'))
if captchaParams.get('proxy') and not captchaParams.get('no_proxy'):
captchaMap = {
'reCaptcha': NoCaptchaTask,
'hCaptcha': HCaptchaTask
}
proxy = self.parseProxy(
captchaParams.get('proxy', {}).get('https'),
captchaParams.get('User-Agent', '')
)
task = captchaMap[captchaType](
url,
siteKey,
**proxy
)
else:
captchaMap = {
'reCaptcha': NoCaptchaTaskProxylessTask,
'hCaptcha': HCaptchaTaskProxyless
}
task = captchaMap[captchaType](url, siteKey)
if not hasattr(client, 'createTaskSmee'):
raise NotImplementedError(
"Please upgrade 'python_anticaptcha' via pip or download it from "
"https://github.com/ad-m/python-anticaptcha/tree/hcaptcha"
)
job = client.createTaskSmee(task, timeout=180)
try:
job.join(maximum_time=180)
except (AnticaptchaException) as e:
raise CaptchaTimeout('{}'.format(getattr(e, 'message', e)))
if 'solution' in job._last_result:
return job.get_solution_response()
else:
raise CaptchaAPIError('Job did not return `solution` key in payload.')
# ------------------------------------------------------------------------------- #
captchaSolver()
-75
View File
@@ -1,75 +0,0 @@
from __future__ import absolute_import
from ..exceptions import (
reCaptchaParameter,
reCaptchaTimeout,
reCaptchaAPIError
)
try:
from python_anticaptcha import (
AnticaptchaClient,
NoCaptchaTaskProxylessTask,
HCaptchaTaskProxyless,
AnticaptchaException
)
except ImportError:
raise ImportError(
"Please install/upgrade the python module 'python_anticaptcha' via "
"pip install python-anticaptcha or https://github.com/ad-m/python-anticaptcha/"
)
import sys
from . import reCaptcha
class captchaSolver(reCaptcha):
def __init__(self):
if sys.modules['python_anticaptcha'].__version__ < '0.6':
raise ImportError(
"Please upgrade the python module 'python_anticaptcha' via "
"pip install -U python-anticaptcha or https://github.com/ad-m/python-anticaptcha/"
)
super(captchaSolver, self).__init__('anticaptcha')
# ------------------------------------------------------------------------------- #
def getCaptchaAnswer(self, captchaType, url, siteKey, reCaptchaParams):
if not reCaptchaParams.get('api_key'):
raise reCaptchaParameter("anticaptcha: Missing api_key parameter.")
client = AnticaptchaClient(reCaptchaParams.get('api_key'))
if reCaptchaParams.get('proxy'):
client.session.proxies = reCaptchaParams.get('proxies')
captchaMap = {
'reCaptcha': NoCaptchaTaskProxylessTask,
'hCaptcha': HCaptchaTaskProxyless
}
task = captchaMap[captchaType](url, siteKey)
if not hasattr(client, 'createTaskSmee'):
raise NotImplementedError(
"Please upgrade 'python_anticaptcha' via pip or download it from "
"https://github.com/ad-m/python-anticaptcha/tree/hcaptcha"
)
job = client.createTaskSmee(task, timeout=180)
try:
job.join(maximum_time=180)
except (AnticaptchaException) as e:
raise reCaptchaTimeout('{}'.format(getattr(e, 'message', e)))
if 'solution' in job._last_result:
return job.get_solution_response()
else:
raise reCaptchaAPIError('Job did not return `solution` key in payload.')
# ------------------------------------------------------------------------------- #
captchaSolver()