#
Example implementation
First of all: Regardless of the programming language used, it is crucial to ensure the use of an appropriate HTTP client that can accurately mimic a browser’s behavior and handle TLS as browsers do. This ensures that communication with servers closely resembles actual browser traffic, which is essential for bypassing certain website security mechanisms. In Python, this can be achieved using the tls_client library, for example, by creating a session with from tls_client import Session. For curl, you can use curl-impersonate, a modified version of curl designed to better emulate web browsers.
import re
import time
from tls_client import Session
from requests import post
PROXY = None
URL = "https://www.footlocker.pt/en/product/~/314216975004.html"
UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
RAPIDAPI_HOST = "https://datadome-cookie-api.p.rapidapi.com"
RAPIDAPI_KEY = "FILL_YOUR_API_KEY_HERE"
def save_response_to_file(response, step):
"""Save both response content and headers to separate log files"""
filename = f"{sanitized_url}_{timestamp}_step{step}_text.log"
with open(filename, 'w', encoding='utf-8') as f:
f.write(response.text)
print(f"STEP{step}: response saved to file: {filename}")
filename = f"{sanitized_url}_{timestamp}_step{step}_headers.log"
with open(filename, 'w', encoding='utf-8') as f:
f.write(f"Status Code: {response.status_code}\n\n")
f.write("Headers:\n")
for header, value in response.headers.items():
f.write(f"{header}: {value}\n")
print(f"STEP{step}: headers headers saved to file: {filename}")
if __name__ == "__main__":
sanitized_url = re.sub(r'[^\w\-_\. ]', '_', URL)
timestamp = int(time.time())
session = Session(client_identifier="chrome_111")
print('Opening URL ', URL)
# -------------------------------
# STEP 1 - Try to fetch page
# -------------------------------
headers = {
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8',
'accept-language': 'en-US,en;q=0.8',
'priority': 'u=0, i',
'sec-ch-ua': '"Brave";v="129", "Not=A?Brand";v="8", "Chromium";v="129"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'sec-gpc': '1',
'upgrade-insecure-requests': '1',
'user-agent': UA
}
response = session.get(URL, headers=headers, proxy=PROXY)
# -------------------------------
# Save response to file
# -------------------------------
save_response_to_file(response, 1)
# -------------------------------
# Check if we received challenge page
# -------------------------------
if not (("geo.captcha-delivery.com" in response.text or \
"interstitial.captcha-delivery.com" in response.text) \
and response.status_code == 403):
print("Page loaded successfully, no challenge found")
exit(0)
# -------------------------------
# STEP2 - build url to challenge
# -------------------------------
response = post(
f"{RAPIDAPI_HOST}/build",
headers={
"X-RapidApi-Key": RAPIDAPI_KEY
},
json={
"datadome": session.cookies.get_dict().get("datadome"),
"referer": URL,
"html": response.text
}
)
save_response_to_file(response, 2)
response = response.json()
challenge_url = response.get("url")
challenge_type = response.get("challenge_type")
if response.status_code != 200:
print("Failed to build url, http status code: ", response.status_code)
exit(0)
# -------------------------------
# STEP3 - fetch the challenge page
# -------------------------------
print('Fetching challenge page...')
challenge = session.get(
challenge_url,
headers={
'Host': 'geo.captcha-delivery.com',
'sec-ch-ua': '"Not/A)Brand";v="8", "Chromium";v="128", "Google Chrome";v="128"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"macOS"',
'Upgrade-Insecure-Requests': '1',
'User-Agent': UA,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'Sec-Fetch-Site': 'cross-site',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Dest': 'iframe',
'Referer': URL,
'Accept-Language': 'en-GB,en;q=0.9',
},
proxy = PROXY
)
save_response_to_file(challenge, 3)
# -------------------------------
# STEP4 - solve datadome challenge
# -------------------------------
print(f"Solving {response['challenge_type']} challenge...")
response = post(
f"{RAPIDAPI_HOST}/solve",
headers={
"X-RapidApi-Key": RAPIDAPI_KEY,
# optional, but highly recommended
"User-Agent": UA,
"Accept-Language": "en-GB,en;q=0.9",
"Sec-Ch-Ua": '"Not/A)Brand";v="8", "Chromium";v="128", "Google Chrome";v="128"',
},
json={
"html": challenge.text,
}
)
save_response_to_file(response, 4)
if response.status_code != 200:
print("Failed to solve challenge, http status code: ", response.status_code)
exit(0)
data = response.json()
# -------------------------------
# STEP5 - post solution to datadome
# -------------------------------
print("Posting solution... to ", data["url"])
res = session.post(
data["url"],
data=data["payload"],
headers={
'Host': 'geo.captcha-delivery.com',
'sec-ch-ua': headers['sec-ch-ua'],
'sec-ch-ua-platform': '"macOS"',
'sec-ch-ua-mobile': '?0',
'User-Agent': UA,
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Accept': '*/*',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': challenge_url,
'Accept-Language': headers['accept-language'],
},
proxy=PROXY
)
if res.status_code != 200:
print("Datadome rejected our payload, http status code: ", res.status_code)
exit(0)
print('Datadome response after receiving solution: ', res.status_code)
data = res.json()
save_response_to_file(res, 5)
# -------------------------------
# Use provided cookie
# -------------------------------
if cookie := data["cookie"].split("datadome=")[1].split("; ")[0]:
print(f"Got datadome cookie => {cookie[:30]}...")
del session.cookies['datadome']
session.cookies.set("datadome", cookie, )
# -------------------------------
# STEP6 - try to load page again
# -------------------------------
print('Loading page again...')
headers['sec-fetch-user'] = '?1'
headers['sec-fetch-dest'] = 'document'
headers['sec-fetch-site'] = 'same-origin'
response = session.get(URL, headers=headers, proxy=PROXY)
save_response_to_file(response, 6)
if (("geo.captcha-delivery.com" in response.text or \
"interstitial.captcha-delivery.com" in response.text) \
and response.status_code == 403):
print("Passing datadome failed, challenge found")
exit(0)
print('Page loaded successfully, no challenge found')