Skip to content

Commit

Permalink
custom exceptions addtions / fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
VeNoMouS committed Feb 14, 2020
1 parent fc9bf19 commit 702abb6
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 13,863 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ Alternatively, clone this repository and run `python setup.py install`.

- Python 2.7 - 3.x
- **[Requests](https://github.com/kennethreitz/requests)** >= 2.9.2
- **[Brotli](https://pypi.org/project/Brotli/)** >= 1.0.7
- **[requests_toolbelt](https://pypi.org/project/requests-toolbelt/)** >= 0.9.1

`python setup.py install` will install the Python dependencies automatically. The javascript interpreters and/or engines you decide to use are the only things you need to install yourself, excluding js2py which is part of the requirements as the default.
Expand Down
21 changes: 13 additions & 8 deletions cloudscraper/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import os
import re
import sys
import ssl
Expand Down Expand Up @@ -43,6 +44,10 @@
except ImportError:
from urllib.parse import urlparse

# Add exceptions path
sys.path.append(os.path.join(os.path.dirname(__file__), 'exceptions'))
import cloudflare_exceptions # noqa: E402

# ------------------------------------------------------------------------------- #

__version__ = '1.2.21'
Expand Down Expand Up @@ -198,7 +203,7 @@ def request(self, method, url, *args, **kwargs):
sys.tracebacklimit = 0
_ = self._solveDepthCnt
self._solveDepthCnt = 0
raise RuntimeError(
raise cloudflare_exceptions.Cloudflare_Loop_Protection(
"!!Loop Protection!! We have tried to solve {} time(s) in a row.".format(_)
)

Expand Down Expand Up @@ -281,7 +286,7 @@ def is_Firewall_Blocked(resp):
def is_Challenge_Request(self, resp):
if self.is_Firewall_Blocked(resp):
sys.tracebacklimit = 0
raise RuntimeError('Cloudflare has blocked this request (Code 1020 Detected).')
raise cloudflare_exceptions.Cloudflare_Block('Cloudflare has blocked this request (Code 1020 Detected).')

if self.is_reCaptcha_Challenge(resp) or self.is_IUAM_Challenge(resp):
return True
Expand Down Expand Up @@ -319,7 +324,7 @@ def unescape(html_text):

except AttributeError:
sys.tracebacklimit = 0
raise RuntimeError(
raise cloudflare_exceptions.Cloudflare_Error_IUAM(
"Cloudflare IUAM detected, unfortunately we can't extract the parameters correctly."
)

Expand All @@ -330,7 +335,7 @@ def unescape(html_text):
interpreter
).solveChallenge(body, hostParsed.netloc)
except Exception as e:
raise RuntimeError(
raise cloudflare_exceptions.Cloudflare_Error_IUAM(
'Unable to parse Cloudflare anti-bots page: {}'.format(
getattr(e, 'message', e)
)
Expand Down Expand Up @@ -359,7 +364,7 @@ def reCaptcha_Challenge_Response(provider, provider_params, body, url):
).groupdict()
except (AttributeError):
sys.tracebacklimit = 0
raise RuntimeError(
raise cloudflare_exceptions.Cloudflare_Error_reCaptcha(
"Cloudflare reCaptcha detected, unfortunately we can't extract the parameters correctly."
)

Expand Down Expand Up @@ -406,7 +411,7 @@ def Challenge_Response(self, resp, **kwargs):

if not self.recaptcha or not isinstance(self.recaptcha, dict) or not self.recaptcha.get('provider'):
sys.tracebacklimit = 0
raise RuntimeError(
raise cloudflare_exceptions.Cloudflare_reCaptcha_Provider(
"Cloudflare reCaptcha detected, unfortunately you haven't loaded an anti reCaptcha provider "
"correctly via the 'recaptcha' parameter."
)
Expand Down Expand Up @@ -442,7 +447,7 @@ def Challenge_Response(self, resp, **kwargs):
self.delay = delay
except (AttributeError, ValueError):
sys.tracebacklimit = 0
raise RuntimeError("Cloudflare IUAM possibility malformed, issue extracing delay value.")
raise cloudflare_exceptions.Cloudflare_Error_IUAM("Cloudflare IUAM possibility malformed, issue extracing delay value.")

sleep(self.delay)

Expand Down Expand Up @@ -590,7 +595,7 @@ def get_tokens(cls, url, **kwargs):
break
else:
sys.tracebacklimit = 0
raise RuntimeError(
raise cloudflare_exceptions.Cloudflare_Error_IUAM(
"Unable to find Cloudflare cookies. Does the site actually "
"have Cloudflare IUAM (I'm Under Attack Mode) enabled?"
)
Expand Down
Empty file.
31 changes: 31 additions & 0 deletions cloudscraper/exceptions/cloudflare_exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ------------------------------------------------------------------------------- #


class Cloudflare_Loop_Protection(Exception):
"""
Raise error for recursive depth protection
"""


class Cloudflare_Block(Exception):
"""
Raise error for Cloudflare 1020 block
"""


class Cloudflare_Error_IUAM(Exception):
"""
Raise error for problem extracting IUAM paramters from Cloudflare payload
"""


class Cloudflare_Error_reCaptcha(Exception):
"""
Raise error for problem extracting reCaptcha paramters from Cloudflare payload
"""


class Cloudflare_reCaptcha_Provider(Exception):
"""
Raise error for reCaptcha from Cloudflare, no provider loaded.
"""
Original file line number Diff line number Diff line change
@@ -1,49 +1,49 @@
# ------------------------------------------------------------------------------- #


class reCaptchaServiceUnavailable(Exception):
class reCaptcha_Service_Unavailable(Exception):
"""
Raise error for external services that cannot be reached
"""


class reCaptchaErrorFromAPI(Exception):
class reCaptcha_Error_From_API(Exception):
"""
Raise error for error from API response.
"""


class reCaptchaAccountError(Exception):
class reCaptcha_Account_Error(Exception):
"""
Raise error for reCaptcha provider account problem.
"""


class reCaptchaTimeout(Exception):
class reCaptcha_Timeout(Exception):
"""
Raise error for reCaptcha provider taking too long.
"""


class reCaptchaBadParameter(Exception):
class reCaptcha_Bad_Parameter(NotImplementedError):
"""
Raise error for bad or missing Parameter.
"""


class reCaptchaBadJobID(Exception):
class reCaptcha_Bad_Job_ID(Exception):
"""
Raise error for invalid job id.
"""


class reCaptchaReportError(Exception):
class reCaptcha_Report_Error(Exception):
"""
Raise error for reCaptcha provider unable to report bad solve.
"""


class reCaptchaImportError(Exception):
class reCaptcha_Import_Error(Exception):
"""
Raise error for reCaptcha, cannot import a module.
"""
22 changes: 11 additions & 11 deletions cloudscraper/reCaptcha/2captcha.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
from __future__ import absolute_import

import requests
from . import exceptions
import reCaptcha_exceptions

try:
import polling
except ImportError:
import sys
sys.tracebacklimit = 0
raise exceptions.reCaptchaImportError(
raise reCaptcha_exceptions.reCaptcha_Import_Error(
"Please install the python module 'polling' via pip or download it from "
"https://github.com/justiniso/polling/"
)
Expand All @@ -28,7 +28,7 @@ def __init__(self):
@staticmethod
def checkErrorStatus(response, request_type):
if response.status_code in [500, 502]:
raise exceptions.reCaptchaServiceUnavailable('2Captcha: Server Side Error {}'.format(response.status_code))
raise reCaptcha_exceptions.reCaptcha_Service_Unavailable('2Captcha: Server Side Error {}'.format(response.status_code))

errors = {
'in.php': {
Expand Down Expand Up @@ -75,7 +75,7 @@ def checkErrorStatus(response, request_type):
}

if response.json().get('status') is False and response.json().get('request') in errors.get(request_type):
raise exceptions.reCaptchaErrorFromAPI(
raise reCaptcha_exceptions.reCaptcha_Error_From_API(
'{} {}'.format(
response.json().get('request'),
errors.get(request_type).get(response.json().get('request'))
Expand All @@ -86,7 +86,7 @@ def checkErrorStatus(response, request_type):

def reportJob(self, jobID):
if not jobID:
raise exceptions.reCaptchaBadJobID(
raise reCaptcha_exceptions.reCaptcha_Bad_Job_ID(
"2Captcha: Error bad job id to request reCaptcha."
)

Expand Down Expand Up @@ -116,7 +116,7 @@ def _checkRequest(response):
if response:
return True
else:
raise exceptions.reCaptchaReportError(
raise reCaptcha_exceptions.reCaptcha_Report_Error(
"2Captcha: Error - Failed to report bad reCaptcha solve."
)

Expand Down Expand Up @@ -152,7 +152,7 @@ def _checkRequest(response):
if response:
return response.json().get('request')
else:
raise exceptions.reCaptchaTimeout(
raise reCaptcha_exceptions.reCaptcha_Timeout(
"2Captcha: Error failed to solve reCaptcha."
)

Expand Down Expand Up @@ -188,7 +188,7 @@ def _checkRequest(response):
if response:
return response.json().get('request')
else:
raise exceptions.reCaptchaBadJobID(
raise reCaptcha_exceptions.reCaptcha_Bad_Job_ID(
'2Captcha: Error no job id was returned.'
)

Expand All @@ -198,7 +198,7 @@ def getCaptchaAnswer(self, site_url, site_key, reCaptchaParams):
jobID = None

if not reCaptchaParams.get('api_key'):
raise exceptions.reCaptchaBadParameter(
raise reCaptcha_exceptions.reCaptcha_Bad_Parameter(
"2Captcha: Missing api_key parameter."
)

Expand All @@ -215,11 +215,11 @@ def getCaptchaAnswer(self, site_url, site_key, reCaptchaParams):
if jobID:
self.reportJob(jobID)
except polling.TimeoutException:
raise exceptions.reCaptchaTimeout(
raise reCaptcha_exceptions.reCaptcha_Timeout(
"2Captcha: reCaptcha solve took to long and also failed reporting the job the job id {}.".format(jobID)
)

raise exceptions.reCaptchaTimeout(
raise reCaptcha_exceptions.reCaptcha_Timeout(
"2Captcha: reCaptcha solve took to long to execute job id {}, aborting.".format(jobID)
)

Expand Down
20 changes: 10 additions & 10 deletions cloudscraper/reCaptcha/9kw.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import re
import requests
from . import exceptions
import reCaptcha_exceptions

try:
import polling
except ImportError:
import sys
sys.tracebacklimit = 0
raise exceptions.reCaptchaImportError(
raise reCaptcha_exceptions.reCaptcha_Import_Error(
"Please install the python module 'polling' via pip or download it from "
"https://github.com/justiniso/polling/"
)
Expand All @@ -30,7 +30,7 @@ def __init__(self):
@staticmethod
def checkErrorStatus(response):
if response.status_code in [500, 502]:
raise exceptions.reCaptchaServiceUnavailable(
raise reCaptcha_exceptions.reCaptcha_Service_Unavailable(
'9kw: Server Side Error {}'.format(response.status_code)
)

Expand Down Expand Up @@ -93,17 +93,17 @@ def checkErrorStatus(response):

if response.text.startswith('{'):
if response.json().get('error'):
raise exceptions.reCaptchaErrorFromAPI(error_codes.get(int(response.json().get('error'))))
raise reCaptcha_exceptions.reCaptcha_Error_From_API(error_codes.get(int(response.json().get('error'))))
else:
error_code = int(re.search(r'^00(?P<error_code>\d+)', response.text).groupdict().get('error_code', 0))
if error_code:
raise exceptions.reCaptchaErrorFromAPI(error_codes.get(error_code))
raise reCaptcha_exceptions.reCaptcha_Error_From_API(error_codes.get(error_code))

# ------------------------------------------------------------------------------- #

def requestJob(self, jobID):
if not jobID:
raise exceptions.reCaptchaBadJobID(
raise reCaptcha_exceptions.reCaptcha_Bad_Job_ID(
"9kw: Error bad job id to request reCaptcha against."
)

Expand Down Expand Up @@ -134,7 +134,7 @@ def _checkRequest(response):
if response:
return response.json().get('answer')
else:
raise exceptions.reCaptchaTimeout("9kw: Error failed to solve reCaptcha.")
raise reCaptcha_exceptions.reCaptcha_Timeout("9kw: Error failed to solve reCaptcha.")

# ------------------------------------------------------------------------------- #

Expand Down Expand Up @@ -170,15 +170,15 @@ def _checkRequest(response):
if response:
return response.json().get('captchaid')
else:
raise exceptions.reCaptchaBadJobID('9kw: Error no valid job id was returned.')
raise reCaptcha_exceptions.reCaptcha_Bad_Job_ID('9kw: Error no valid job id was returned.')

# ------------------------------------------------------------------------------- #

def getCaptchaAnswer(self, site_url, site_key, reCaptchaParams):
jobID = None

if not reCaptchaParams.get('api_key'):
raise exceptions.reCaptchaBadParameter("9kw: Missing api_key parameter.")
raise reCaptcha_exceptions.reCaptcha_Bad_Parameter("9kw: Missing api_key parameter.")

self.api_key = reCaptchaParams.get('api_key')

Expand All @@ -192,7 +192,7 @@ def getCaptchaAnswer(self, site_url, site_key, reCaptchaParams):
jobID = self.requestSolve(site_url, site_key)
return self.requestJob(jobID)
except polling.TimeoutException:
raise exceptions.reCaptchaTimeout(
raise reCaptcha_exceptions.reCaptcha_Timeout(
"9kw: reCaptcha solve took to long to execute 'captchaid' {}, aborting.".format(jobID)
)

Expand Down
8 changes: 4 additions & 4 deletions cloudscraper/reCaptcha/anticaptcha.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from __future__ import absolute_import

import sys
from . import exceptions
import reCaptcha_exceptions

try:
from python_anticaptcha import AnticaptchaClient, NoCaptchaTaskProxylessTask
except ImportError:
sys.tracebacklimit = 0
raise exceptions.reCaptchaImportError(
raise reCaptcha_exceptions.reCaptcha_Import_Error(
"Please install the python module 'python_anticaptcha' via pip or download it from "
"https://github.com/ad-m/python-anticaptcha"
)
Expand All @@ -24,7 +24,7 @@ def __init__(self):

def getCaptchaAnswer(self, site_url, site_key, reCaptchaParams):
if not reCaptchaParams.get('api_key'):
raise exceptions.reCaptchaBadParameter("anticaptcha: Missing api_key parameter.")
raise reCaptcha_exceptions.reCaptcha_Bad_Parameter("anticaptcha: Missing api_key parameter.")

client = AnticaptchaClient(reCaptchaParams.get('api_key'))

Expand All @@ -35,7 +35,7 @@ def getCaptchaAnswer(self, site_url, site_key, reCaptchaParams):

if not hasattr(client, 'createTaskSmee'):
sys.tracebacklimit = 0
raise exceptions.reCaptchaImportError(
raise reCaptcha_exceptions.reCaptcha_Import_Error(
"Please upgrade 'python_anticaptcha' via pip or download it from https://github.com/ad-m/python-anticaptcha"
)

Expand Down
Loading

0 comments on commit 702abb6

Please sign in to comment.