-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from ZennoLab/task/CML-1508
- Loading branch information
Showing
17 changed files
with
308 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from typing import Optional, List, Dict | ||
|
||
from .baseRequest import BaseRequest | ||
|
||
class CustomTaskRequestBase(BaseRequest): | ||
captchaClass: str # Class(subtype) of ComplexImageTask | ||
type: str = "CustomTask" # Recognition task type | ||
websiteUrl: str # Address of a webpage with captcha | ||
userAgent: Optional[str] = None # It is required that you use a signature of a modern browser | ||
domains: Optional[List[str]] = None # Collection with base64 encoded images. Must be populated if <see cref="ImageUrls"/> not. |
36 changes: 36 additions & 0 deletions
36
capmonstercloud_client/requests/DataDomeCustomTaskProxylessRequest.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
from typing import Dict, Union | ||
from pydantic import Field, validator | ||
|
||
from .DataDomeCustomTaskRequestBase import DataDomeCustomTaskRequestBase | ||
|
||
class DataDomeCustomTaskProxylessRequest(DataDomeCustomTaskRequestBase): | ||
metadata : Dict[str, str] | ||
|
||
@validator('metadata') | ||
def validate_metadata(cls, value): | ||
if value.get('datadomeCookie') is None: | ||
raise ValueError(f'Expect that datadomeCookie will be defined.') | ||
if value.get('captchaUrl') and value.get('htmlPageBase64'): | ||
raise ValueError(f'Expected only one of [captchaUrl, htmlPageBase64]') | ||
elif value.get('captchaUrl'): | ||
if not isinstance(value.get('captchaUrl'), str): | ||
raise ValueError(f'Expect that type imagesUrls array will be <str>, got {type(value.get("captchaUrl"))}') | ||
return {i: value[i] for i in value if i != 'htmlPageBase64'} | ||
elif value.get('htmlPageBase64'): | ||
if not isinstance(value.get('htmlPageBase64'), str): | ||
raise ValueError(f'Expect that type imagesUrls array will be <str>, got {type(value.get("htmlPageBase64"))}') | ||
return {i: value[i] for i in value if i != 'captchaUrl'} | ||
else: | ||
raise ValueError(f'Expected one of [captchaUrl, htmlPageBase64]') | ||
|
||
def getTaskDict(self) -> Dict[str, Union[str, int, bool]]: | ||
task = {} | ||
task['type'] = self.type | ||
task['class'] = self.captchaClass | ||
task['websiteURL'] = self.websiteUrl | ||
task['metadata'] = self.metadata | ||
if self.userAgent is not None: | ||
task['userAgent'] = self.userAgent | ||
if self.domains is not None: | ||
task['domains'] = self.domains | ||
return task |
42 changes: 42 additions & 0 deletions
42
capmonstercloud_client/requests/DataDomeCustomTaskRequest.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
from typing import Dict, Union | ||
from pydantic import Field, validator | ||
from .DataDomeCustomTaskRequestBase import DataDomeCustomTaskRequestBase | ||
from .proxy_info import ProxyInfo | ||
|
||
class DataDomeCustomTaskRequest(DataDomeCustomTaskRequestBase, ProxyInfo): | ||
metadata : Dict[str, str] | ||
|
||
@validator('metadata') | ||
def validate_metadata(cls, value): | ||
if value.get('datadomeCookie') is None: | ||
raise TypeError(f'Expect that datadomeCookie will be defined.') | ||
if value.get('captchaUrl') and value.get('htmlPageBase64'): | ||
raise TypeError(f'Expected only one of [captchaUrl, htmlPageBase64]') | ||
elif value.get('captchaUrl'): | ||
if not isinstance(value.get('captchaUrl'), str): | ||
raise TypeError(f'Expect that type imagesUrls array will be <str>, got {type(value.get("captchaUrl"))}') | ||
return {i: value[i] for i in value if i != 'htmlPageBase64'} | ||
elif value.get('htmlPageBase64'): | ||
if not isinstance(value.get('htmlPageBase64'), str): | ||
raise TypeError(f'Expect that type imagesUrls array will be <str>, got {type(value.get("htmlPageBase64"))}') | ||
return {i: value[i] for i in value if i != 'captchaUrl'} | ||
else: | ||
raise TypeError(f'Expected one of [captchaUrl, htmlPageBase64]') | ||
|
||
def getTaskDict(self) -> Dict[str, Union[str, int, bool]]: | ||
task = {} | ||
task['type'] = self.type | ||
task['class'] = self.captchaClass | ||
task['websiteURL'] = self.websiteUrl | ||
task['proxyType'] = self.proxyType | ||
task['proxyAddress'] = self.proxyAddress | ||
task['proxyPort'] = self.proxyPort | ||
task['proxyLogin'] = self.proxyLogin | ||
task['proxyPassword'] = self.proxyPassword | ||
task['domains'] = self.domains | ||
task['metadata'] = self.metadata | ||
if self.userAgent is not None: | ||
task['userAgent'] = self.userAgent | ||
if self.domains is not None: | ||
task['domains'] = self.domains | ||
return task |
8 changes: 8 additions & 0 deletions
8
capmonstercloud_client/requests/DataDomeCustomTaskRequestBase.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from typing import Dict, Union | ||
from pydantic import Field | ||
|
||
from .CustomTaskRequestBase import CustomTaskRequestBase | ||
|
||
class DataDomeCustomTaskRequestBase(CustomTaskRequestBase): | ||
type: str = Field(default='CustomTask') | ||
captchaClass: str = Field(default='DataDome') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
1.3.4 | ||
1.4.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import os | ||
import time | ||
import asyncio | ||
|
||
from capmonstercloudclient.requests import DataDomeCustomTaskProxylessRequest | ||
from capmonstercloudclient import ClientOptions, CapMonsterClient | ||
|
||
async def solve_captcha_sync(num_requests): | ||
return [await cap_monster_client.solve_captcha(datadome_request) for _ in range(num_requests)] | ||
|
||
async def solve_captcha_async(num_requests): | ||
tasks = [asyncio.create_task(cap_monster_client.solve_captcha(datadome_request)) | ||
for _ in range(num_requests)] | ||
return await asyncio.gather(*tasks, return_exceptions=True) | ||
|
||
if __name__ == '__main__': | ||
key = os.getenv('API_KEY') | ||
client_options = ClientOptions(api_key=key) | ||
cap_monster_client = CapMonsterClient(options=client_options) | ||
metadata = {'captchaUrl': 'https://geo.captcha-delivery.com/captcha/?initialCid=AHrlqAAAAAMAJxx4dfgwjzwAQW0ctQ%3D%3D&hash=D66B23AC3F48A302A7654416846381&cid=d3k5rbDsu8cq0kmPHISS3hsC3f4qeL_K12~G33PrE4fbkmDYSul6l0Ze_aG5sUHLKG0676UpTv6GFvUgIActglZF33GTodOoRhEDkMMsuWTodlYa3YYQ9xKy9J89PAWh&t=fe&referer=https%3A%2F%2Fantoinevastel.com%2Fbots%2Fdatadome&s=21705&e=04fc682817ba89bf8fa4b18031fa53294fa0fb7449d95c036a1986413e6dfc7d', | ||
'datadomeCookie': 'datadome=d3k5rbDsu8cq0kmPHISS3hsC3f4qeL_K12~G33PrE4fbkmDYSul6l0Ze_aG5sUHLKG0676UpTv6GFvUgIActglZF33GTodOoRhEDkMMsuWTodlYa3YYQ9xKy9J89PAWh'} | ||
datadome_request = DataDomeCustomTaskProxylessRequest(websiteUrl='https://antoinevastel.com/bots/datadome', | ||
metadata=metadata | ||
) | ||
nums = 3 | ||
|
||
# Sync test | ||
sync_start = time.time() | ||
sync_responses = asyncio.run(solve_captcha_sync(nums)) | ||
print(f'average execution time sync {1/((time.time()-sync_start)/nums):0.2f} ' \ | ||
f'resp/sec\nsolution: {sync_responses[0]}') | ||
|
||
# Async test | ||
async_start = time.time() | ||
async_responses = asyncio.run(solve_captcha_async(nums)) | ||
print(f'average execution time async {1/((time.time()-async_start)/nums):0.2f} ' \ | ||
f'resp/sec\nsolution: {async_responses[0]}') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import unittest | ||
import asyncio | ||
import os | ||
|
||
from pydantic.error_wrappers import ValidationError | ||
from capmonstercloudclient.requests import DataDomeCustomTaskProxylessRequest | ||
from capmonstercloudclient import CapMonsterClient, ClientOptions | ||
|
||
def get_all_keys(dictionary): | ||
all_values = [] | ||
def recursive_items(dictionary): | ||
for key, value in dictionary.items(): | ||
if type(value) is dict: | ||
all_values.append(key) | ||
recursive_items(value) | ||
else: | ||
all_values.append(key) | ||
return all_values | ||
return recursive_items(dictionary) | ||
|
||
class DataDomeOutsTest(unittest.TestCase): | ||
|
||
def testOuts(self): | ||
required_outs = ['domains', 'datadome', 'cookies'] | ||
api_key = os.getenv('API_KEY') | ||
options = ClientOptions(api_key=api_key) | ||
client = CapMonsterClient(options) | ||
metadata = {'captchaUrl': 'https://geo.captcha-delivery.com/captcha/?initialCid=AHrlqAAAAAMAJxx4dfgwjzwAQW0ctQ%3D%3D&hash=D66B23AC3F48A302A7654416846381&cid=d3k5rbDsu8cq0kmPHISS3hsC3f4qeL_K12~G33PrE4fbkmDYSul6l0Ze_aG5sUHLKG0676UpTv6GFvUgIActglZF33GTodOoRhEDkMMsuWTodlYa3YYQ9xKy9J89PAWh&t=fe&referer=https%3A%2F%2Fantoinevastel.com%2Fbots%2Fdatadome&s=21705&e=04fc682817ba89bf8fa4b18031fa53294fa0fb7449d95c036a1986413e6dfc7d', | ||
'datadomeCookie': 'datadome=d3k5rbDsu8cq0kmPHISS3hsC3f4qeL_K12~G33PrE4fbkmDYSul6l0Ze_aG5sUHLKG0676UpTv6GFvUgIActglZF33GTodOoRhEDkMMsuWTodlYa3YYQ9xKy9J89PAWh'} | ||
|
||
request = DataDomeCustomTaskProxylessRequest(websiteUrl='https://antoinevastel.com/bots/datadome', | ||
metadata=metadata) | ||
result = asyncio.run(client.solve_captcha(request)) | ||
|
||
for i in required_outs: | ||
self.assertTrue(i in get_all_keys(result)) | ||
|
||
|
||
if __name__ == '__main__': | ||
unittest.main() | ||
|
Oops, something went wrong.