Copy
import requests
API_KEY = "" # your solv.now api key
PROXY = "" # url format. protocol://[user:pass@]host:port
def solve_turnstile(
url: str,
sitekey: str,
proxy: str,
action: str | None = None,
cdata: str | None = None,
):
"""
Solves a Turnstile captcha using solv.now API.
Args:
url (str): The URL of the page containing the Turnstile captcha.
sitekey (str): The sitekey of the Turnstile captcha.
proxy (str): The proxy to use for the request.
action (str | None): The action parameter for the Turnstile captcha.
cdata (str | None): The cdata parameter for the Turnstile captcha.
Returns:
str: The token returned by the Turnstile captcha.
Raises:
ValueError: If the sitekey is invalid.
"""
if not sitekey.startswith("0x"):
raise ValueError("Invalid sitekey")
# An action cannot be empty, only null or alphanumeric.
if action == "":
action = None
# Same logic goes for cdata.
if cdata == "":
cdata = None
response = requests.post(
"https://api.solv.now/v1/task/execute",
headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"},
json={
"task_type": "turnstile",
"task_data": {
"url": url,
"sitekey": sitekey,
"proxy": proxy,
"action": action,
"cdata": cdata,
},
},
)
data = response.json()
if not data.get("success"):
raise Exception(f"Error occurred while solving WAF: {data.get('message')}")
return data["data"]["solution"]["token"]
def main():
url = "https://turnstile-test.vercel.app/"
sitekey = "0x4AAAAAAAA1WzHSsbGWTH88"
token = solve_turnstile(url, sitekey, PROXY, action=None, cdata=None)
# The website lets us check the token.
check_response = requests.post(
"https://turnstile-test.vercel.app/",
data={"cf-turnstile-response": token, "name": "test", "type": "managed"},
)
assert check_response.status_code == 200
print("Success:", check_response.json().get("success"))
if __name__ == "__main__":
main()