Skip to content

Commit eb38897

Browse files
alperensertclaude
andcommitted
feat: add RecaptchaClickTask, HuntTask, and missing API fields
New task types: - RecaptchaClickTask for click-based reCAPTCHA solving - HuntTask for Hunt captcha solving New fields on existing tasks: - cookies on RecaptchaV2Task - pageAction on RecaptchaV2EnterpriseTask - isEnterprise on RecaptchaV3Task - nocache on all reCAPTCHA task types (v2, v2e, v3, v3e) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 152dc97 commit eb38897

File tree

8 files changed

+79
-1
lines changed

8 files changed

+79
-1
lines changed

src/capmonster_python/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
"FunCaptchaTask",
2323
"GeeTestV3Task",
2424
"GeeTestV4Task",
25+
"HuntTask",
2526
"ImageToTextTask",
2627
"ImpervaTask",
2728
"ImpervaTaskMetadata",
2829
"MTCaptchaTask",
2930
"ProsopoTask",
31+
"RecaptchaClickTask",
3032
"RecaptchaV2Task",
3133
"RecaptchaV2EnterpriseTask",
3234
"RecaptchaV3Task",

src/capmonster_python/tasks/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88
from .datadome import DataDomeTask, DataDomeMetadata
99
from .funcaptcha import FunCaptchaTask
1010
from .geetest import GeeTestV4Task, GeeTestV3Task
11+
from .hunt import HuntTask
1112
from .image_to_text import ImageToTextTask
1213
from .imperva import ImpervaTask, ImpervaTaskMetadata
1314
from .mtcaptcha import MTCaptchaTask
1415
from .prosopo import ProsopoTask
16+
from .recaptcha_click import RecaptchaClickTask
1517
from .recaptcha_v2 import RecaptchaV2Task
1618
from .recaptcha_v2_enterprise import RecaptchaV2EnterpriseTask
1719
from .recaptcha_v3 import RecaptchaV3Task
@@ -42,11 +44,13 @@
4244
"FunCaptchaTask",
4345
"GeeTestV3Task",
4446
"GeeTestV4Task",
47+
"HuntTask",
4548
"ImageToTextTask",
4649
"ImpervaTask",
4750
"ImpervaTaskMetadata",
4851
"MTCaptchaTask",
4952
"ProsopoTask",
53+
"RecaptchaClickTask",
5054
"RecaptchaV2Task",
5155
"RecaptchaV2EnterpriseTask",
5256
"RecaptchaV3Task",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Optional, Any
2+
3+
from pydantic import Field
4+
5+
from .task import TaskPayload, ProxyPayload, UserAgentPayload
6+
7+
8+
class HuntTask(TaskPayload, UserAgentPayload):
9+
"""
10+
Represents a task for solving Hunt captcha challenges.
11+
12+
Attributes:
13+
websiteURL: The URL of the webpage containing the captcha.
14+
websiteKey: The Hunt captcha site key.
15+
proxy: Optional proxy settings.
16+
"""
17+
type: str = Field(default="HuntTask", frozen=True)
18+
websiteURL: str = Field(..., description='Address of a webpage with captcha.')
19+
websiteKey: str = Field(..., description='Hunt captcha site key.')
20+
proxy: Optional[ProxyPayload] = Field(default=None, description='Proxy settings.')
21+
22+
def to_request(self) -> dict[str, Any]:
23+
base = self.model_dump(exclude_none=True)
24+
proxy_dict = base.pop("proxy", {})
25+
if proxy_dict:
26+
base.update(proxy_dict)
27+
return base
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
from typing import Optional, Any
2+
3+
from pydantic import Field
4+
5+
from .task import TaskPayload, ProxyPayload, UserAgentPayload
6+
7+
8+
class RecaptchaClickTask(TaskPayload, UserAgentPayload):
9+
"""
10+
Represents a task for solving click-based reCAPTCHA challenges.
11+
12+
Attributes:
13+
websiteURL: The URL of the webpage containing the reCAPTCHA challenge.
14+
websiteKey: The site key associated with the reCAPTCHA on the webpage.
15+
isInvisible: When set to True, specifies that the challenge
16+
being solved is an invisible reCAPTCHA.
17+
proxy: Optional proxy settings.
18+
"""
19+
type: str = Field(default="RecaptchaClickTask", frozen=True)
20+
websiteURL: str = Field(..., description='Address of a webpage with captcha.')
21+
websiteKey: str = Field(..., description='reCAPTCHA website key.')
22+
isInvisible: Optional[bool] = Field(default=None,
23+
description='Set to true if you want to solve invisible reCAPTCHA.')
24+
proxy: Optional[ProxyPayload] = Field(default=None, description='Proxy settings.')
25+
26+
def to_request(self) -> dict[str, Any]:
27+
base = self.model_dump(exclude_none=True)
28+
proxy_dict = base.pop("proxy", {})
29+
if proxy_dict:
30+
base.update(proxy_dict)
31+
return base

src/capmonster_python/tasks/recaptcha_v2.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class RecaptchaV2Task(TaskPayload, UserAgentPayload):
3030
'and must be grabbed every time you want to solve a reCAPTCHA v2.')
3131
isInvisible: Optional[bool] = Field(default=None,
3232
description='Set to true if you want to solve invisible reCAPTCHA.')
33+
cookies: Optional[str] = Field(default=None,
34+
description='Additional cookies in the format: cookieName1=value1; cookieName2=value2.')
35+
nocache: Optional[bool] = Field(default=None,
36+
description='Set to true to force fresh token generation (prevents reuse of cached tokens).')
3337
proxy: Optional[ProxyPayload] = Field(default=None, description='Proxy settings.')
3438

3539
def to_request(self) -> dict[str, Any]:

src/capmonster_python/tasks/recaptcha_v2_enterprise.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,18 @@ class RecaptchaV2EnterpriseTask(TaskPayload, UserAgentPayload):
2222
type: str = Field(default="RecaptchaV2EnterpriseTask", frozen=True)
2323
websiteURL: str = Field(..., description='Address of a webpage with Google reCAPTCHA Enterprise.')
2424
websiteKey: str = Field(..., description='reCAPTCHA website key.')
25+
pageAction: Optional[str] = Field(default=None,
26+
description='Action parameter if different from default “verify”.')
2527
enterprisePayload: Optional[str] = Field(default=None,
2628
description='Some implementations of the reCAPTCHA Enterprise widget '
2729
'may contain additional parameters that are passed to the '
28-
'grecaptcha.enterprise.render” method along with the sitekey.')
30+
'grecaptcha.enterprise.render” method along with the sitekey.')
2931
apiDomain: Optional[str] = Field(default=None,
3032
description='Domain address from which to load reCAPTCHA Enterprise. '
3133
'Don\'t use a parameter if you don\'t know why it\'s needed.')
3234
cookies: Optional[str] = Field(default=None, description='Cookies to be sent with the request.')
35+
nocache: Optional[bool] = Field(default=None,
36+
description='Set to true to force fresh token generation (prevents reuse of cached tokens).')
3337
proxy: Optional[ProxyPayload] = Field(default=None, description='Proxy settings.')
3438

3539
def to_request(self) -> dict[str, Any]:

src/capmonster_python/tasks/recaptcha_v3.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class RecaptchaV3Task(TaskPayload):
2525
pageAction: Optional[str] = Field(default=None,
2626
description='Widget action value. Website owner defines what user is doing on '
2727
'the page through this parameter. Default value: verify')
28+
isEnterprise: Optional[bool] = Field(default=None,
29+
description='Set to true to solve as Enterprise (equivalent to RecaptchaV3EnterpriseTask).')
30+
nocache: Optional[bool] = Field(default=None,
31+
description='Set to true to force fresh token generation (prevents reuse of cached tokens).')
2832

2933
def to_request(self) -> dict[str, Any]:
3034
return self.model_dump(exclude_none=True)

src/capmonster_python/tasks/recaptcha_v3_enterprise.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class RecaptchaV3EnterpriseTask(TaskPayload):
2323
pageAction: Optional[str] = Field(default=None,
2424
description='Widget action value. Website owner defines what user is doing on '
2525
'the page through this parameter. Default value: verify')
26+
nocache: Optional[bool] = Field(default=None,
27+
description='Set to true to force fresh token generation (prevents reuse of cached tokens).')
2628

2729
def to_request(self) -> dict[str, Any]:
2830
return self.model_dump(exclude_none=True)

0 commit comments

Comments
 (0)