Загрузка данных
Ладно. Вернемся к изнаальному скрипту, вот он, работаем с ним:
#!/usr/bin/env python3
"""
AdsPower → Steam OpenID → jabka.to
После успеха:
Enter #1 → взять cookie "token" СЕЙЧАС → POST на /api/accounts
Enter #2 → закрыть браузер + удалить профиль AdsPower
"""
import sys
import time
from urllib.parse import urlparse
import requests
from playwright.sync_api import sync_playwright
# ====================== НАСТРОЙКИ ======================
ADS_API_BASE = "http://local.adspower.net:50325"
API_KEY = "bb191d39891a5425f133816a601e7cba009ea8f9ff6be779"
ACCOUNTS_API = "http://192.168.0.111:5000/api/accounts"
TARGET_URL = (
"https://steamcommunity.com/openid/loginform/"
"?goto=%2Fopenid%2Flogin%3Fopenid.mode%3Dcheckid_setup"
"%26openid.ns%3Dhttp%253A%252F%252Fspecs.openid.net%252Fauth%252F2.0"
"%26openid.identity%3Dhttp%253A%252F%252Fspecs.openid.net%252Fauth%252F2.0%252Fidentifier_select"
"%26openid.claimed_id%3Dhttp%253A%252F%252Fspecs.openid.net%252Fauth%252F2.0%252Fidentifier_select"
"%26openid.return_to%3Dhttps%253A%252F%252Fjabauth.com%252Fapi%252Fusers%252Fauth%252Fsteam%252Fvalidate"
"%253Fregister%253D1%2526r%253Dhttps%25253A%25252F%25252Fjabka.to%25252Fauthenticate"
"%26openid.realm%3Dhttps%253A%252F%252Fjabauth.com"
)
# =======================================================
HEADERS = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}",
}
def api_post(path: str, payload: dict, timeout: int = 60) -> dict:
r = requests.post(f"{ADS_API_BASE}{path}", headers=HEADERS, json=payload, timeout=timeout)
data = r.json()
if data.get("code") != 0:
raise RuntimeError(f"API error {path}: {data.get('msg')} | {data}")
return data
def check_api() -> bool:
try:
r = requests.get(f"{ADS_API_BASE}/status", headers=HEADERS, timeout=5)
return r.status_code == 200
except Exception:
return False
def create_profile() -> str:
payload = {
"name": f"steam_jabka_{int(time.time())}",
"group_id": "0",
"tabs": [TARGET_URL],
"user_proxy_config": {"proxy_soft": "no_proxy"},
"fingerprint_config": {
"automatic_timezone": "1",
"language": ["en-US", "en"],
"flash": "block",
"fonts": ["all"],
"webrtc": "disabled",
"canvas": "1",
"webgl_image": "1",
"webgl": "3",
"audio": "1",
"do_not_track": "true",
"hardware_concurrency": "default",
"device_memory": "default",
"random_ua": {
"ua_browser": ["chrome"],
"ua_system_version": ["Windows 10", "Windows 11"],
},
},
}
data = api_post("/api/v2/browser-profile/create", payload)
profile_id = data["data"]["profile_id"]
print(f"[+] Профиль создан → {profile_id} (№ {data['data']['profile_no']})")
return profile_id
def start_browser(profile_id: str) -> str:
payload = {
"profile_id": profile_id,
"headless": "0",
"last_opened_tabs": "1",
"proxy_detection": "0",
"cdp_mask": "1",
}
data = api_post("/api/v2/browser-profile/start", payload)
ws = data["data"]["ws"]["puppeteer"]
print(f"[+] Браузер запущен → {ws}")
return ws
def stop_browser(profile_id: str):
try:
requests.get(
f"{ADS_API_BASE}/api/v1/browser/stop",
params={"user_id": profile_id},
headers=HEADERS,
timeout=15,
)
print("[*] Браузер закрыт")
except Exception as e:
print(f"[!] Не удалось закрыть браузер: {e}")
def delete_profile(profile_id: str):
try:
data = api_post("/api/v2/browser-profile/delete", {"profile_id": [profile_id]})
print(f"[*] Профиль удалён: {data.get('msg', 'ok')}")
except Exception as e:
print(f"[!] Не удалось удалить профиль: {e}")
def is_jwt(s: str) -> bool:
parts = s.strip().split(".")
return len(parts) == 3 and all(parts)
def parse_login_password(s: str):
if ":" not in s:
return None, None
login, password = s.split(":", 1)
login, password = login.strip(), password.strip()
if login and password:
return login, password
return None, None
def host_is(url: str, *domains: str) -> bool:
try:
host = (urlparse(url).hostname or "").lower()
return any(host == d or host.endswith("." + d) for d in domains)
except Exception:
return False
def visible(el) -> bool:
try:
return el is not None and el.is_visible()
except Exception:
return False
def is_steam_guard_visible(page) -> bool:
for sel in ["#twofactorcode_entry", "#authcode", "input[name='authcode']"]:
try:
el = page.query_selector(sel)
if visible(el):
return True
except Exception:
continue
return False
def get_token_from_cookies(context) -> str | None:
"""Читает cookie name='token' в момент вызова (Enter #1)."""
try:
cookies = context.cookies()
except Exception as e:
print(f"[!] Не удалось прочитать cookies: {e}")
return None
priority_domains = ("jabka.to", "jabauth.com")
candidates = []
for c in cookies:
if c.get("name") != "token":
continue
domain = (c.get("domain") or "").lstrip(".").lower()
value = c.get("value") or ""
if not value:
continue
candidates.append((domain, value))
if not candidates:
print("[!] Cookie 'token' не найден")
names = sorted({c.get("name") for c in cookies})
print(f" Доступные cookies: {names}")
return None
for pref in priority_domains:
for domain, value in candidates:
if domain == pref or domain.endswith("." + pref):
return value
return candidates[0][1]
def post_account(jwt_token: str):
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/155.0.0.0 Safari/537.36"
),
"Content-Type": "application/json",
"Referer": "http://192.168.0.111:5000/",
}
payload = {"jwt_token": jwt_token}
print(f"[*] POST {ACCOUNTS_API}")
print(f" body: {payload}")
try:
r = requests.post(ACCOUNTS_API, headers=headers, json=payload, timeout=30, verify=False)
print(f"[+] Ответ {r.status_code}: {r.text[:500]}")
except Exception as e:
print(f"[!] Ошибка POST: {e}")
def fill_steam_login(page, login: str, password: str):
print("[*] Ищем поля логина Steam...")
page.wait_for_selector(
"input[type='text'], input[type='password'], #steamAccountName",
timeout=30000,
)
time.sleep(1.2)
for selector in ["#steamAccountName", "input[name='username']", "input[type='text']", "form input[type='text']"]:
try:
el = page.query_selector(selector)
if visible(el):
el.click()
el.fill("")
el.type(login, delay=35)
print(f"[+] Логин введён ({selector})")
break
except Exception:
continue
else:
raise RuntimeError("Не удалось найти поле логина")
for selector in ["#steamPassword", "input[name='password']", "input[type='password']", "form input[type='password']"]:
try:
el = page.query_selector(selector)
if visible(el):
el.click()
el.fill("")
el.type(password, delay=35)
print(f"[+] Пароль введён ({selector})")
break
except Exception:
continue
else:
raise RuntimeError("Не удалось найти поле пароля")
time.sleep(0.4)
for sel in [
"button:has-text('Sign in')",
"button:has-text('Войти')",
"button[type='submit']",
"input[type='submit']",
"form button",
]:
try:
btn = page.query_selector(sel)
if visible(btn):
btn.click()
print(f"[+] Первый «Войти» → {sel}")
return
except Exception:
continue
page.keyboard.press("Enter")
print("[+] Enter (fallback)")
def click_openid_confirm(page) -> bool:
selectors = [
"#imageLogin",
"input#imageLogin",
"input.btn_green_white_innerfade[type='submit']",
"input[type='submit'][value='Войти']",
"input[type='submit'][value='Sign In']",
"input[type='submit'][value='Sign in']",
"form#openidForm input[type='submit']",
"form[name='loginForm'] input[type='submit']",
]
for sel in selectors:
try:
el = page.query_selector(sel)
if visible(el):
el.click()
print(f"[+] OpenID «Войти» → {sel}")
return True
except Exception:
continue
try:
page.wait_for_selector("#imageLogin", state="visible", timeout=10000)
el = page.query_selector("#imageLogin")
if el:
el.click()
print("[+] #imageLogin (после wait)")
return True
except Exception:
pass
print("[!] #imageLogin не найдена")
return False
def wait_openid_and_confirm(page, timeout_sec: int = 90) -> bool:
print("[*] Ждём OpenID-подтверждение и жмём «Войти»...")
deadline = time.time() + timeout_sec
guard_warned = False
while time.time() < deadline:
url = page.url
if host_is(url, "jabka.to", "jabauth.com"):
print(f"[+] Уже на целевом домене: {url}")
return True
if is_steam_guard_visible(page):
if not guard_warned:
print("[!] Steam Guard виден — введи код вручную.")
guard_warned = True
time.sleep(2)
continue
guard_warned = False
host = (urlparse(url).hostname or "").lower()
on_steam = "steamcommunity.com" in host
has_btn = visible(page.query_selector("#imageLogin"))
has_card = (
visible(page.query_selector(".OpenID_UserContainer"))
or visible(page.query_selector(".OpenID_loggedInName"))
or visible(page.query_selector(".OpenID_loggedInAccount"))
)
if on_steam and (has_btn or has_card or "/openid/" in url):
if has_btn or has_card:
print(f"[+] OpenID-подтверждение: {url[:90]}...")
time.sleep(0.5)
if click_openid_confirm(page):
time.sleep(2)
if host_is(page.url, "jabka.to", "jabauth.com"):
return True
if visible(page.query_selector("#imageLogin")):
click_openid_confirm(page)
return True
else:
try:
page.wait_for_selector("#imageLogin", state="visible", timeout=5000)
if click_openid_confirm(page):
return True
except Exception:
pass
time.sleep(0.5)
print("[!] Таймаут OpenID")
return False
def wait_until_jabka(page, timeout_sec: int = 150) -> bool:
print("[*] Ждём hostname jabka.to ...")
deadline = time.time() + timeout_sec
while time.time() < deadline:
url = page.url
if host_is(url, "jabka.to"):
print(f"[+] Успех! URL: {url}")
return True
if host_is(url, "jabauth.com"):
print("[+] jabauth.com, ждём редирект...")
time.sleep(1.5)
continue
if visible(page.query_selector("#imageLogin")):
print("[*] #imageLogin ещё видна — кликаем")
click_openid_confirm(page)
time.sleep(1.0)
print(f"[!] Таймаут. URL: {page.url}")
return False
def main():
print("=== AdsPower → Steam OpenID → jabka.to ===\n")
if not check_api():
print("[-] Local API недоступен.")
sys.exit(1)
print("[+] Local API доступен")
profile_id = None
try:
profile_id = create_profile()
time.sleep(1)
ws_endpoint = start_browser(profile_id)
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(ws_endpoint)
context = browser.contexts[0]
page = context.pages[0] if context.pages else context.new_page()
if "steamcommunity.com" not in page.url:
page.goto(TARGET_URL, wait_until="domcontentloaded", timeout=60000)
print("\n" + "=" * 55)
print("Введи JWT или login:password")
print("=" * 55)
user_input = input(">>> ").strip()
if not user_input:
return
# ---------- JWT напрямую ----------
if is_jwt(user_input) or (":" not in user_input and len(user_input) > 40):
token = user_input.strip()
page.goto(
f"https://jabka.to/authenticate?token={token}",
wait_until="domcontentloaded",
timeout=60000,
)
else:
# ---------- login:password ----------
login, password = parse_login_password(user_input)
if not login:
print("[-] Нужен login:password или JWT")
return
print(f"[*] Логин: {login}")
fill_steam_login(page, login, password)
wait_openid_and_confirm(page, timeout_sec=90)
success = wait_until_jabka(page, timeout_sec=150)
if not success:
print("\n[!] Не дождались jabka.to")
print(f" URL: {page.url}")
input("\nEnter — закрыть...")
return
print("\n[✓] Авторизация на jabka.to завершена.")
# ----- Enter #1 → ЧИТАЕМ cookie token СЕЙЧАС → POST -----
print("\n" + "=" * 55)
print("Enter #1 — взять token из cookies и добавить аккаунт в БД")
print("=" * 55)
input(">>> ")
jwt_token = get_token_from_cookies(context)
if jwt_token:
print(f"[JWT] token = {jwt_token}")
post_account(jwt_token)
else:
print("[!] Cookie 'token' не найден — POST пропущен")
manual = input("Вставь JWT вручную (или Enter чтобы пропустить): ").strip()
if manual:
print(f"[JWT] token = {manual}")
post_account(manual)
# ----- Enter #2 → закрыть + удалить -----
print("\n" + "=" * 55)
print("Enter #2 — закрыть браузер и удалить профиль AdsPower")
print("=" * 55)
input(">>> ")
except Exception as e:
print(f"[-] Ошибка: {e}")
raise
finally:
if profile_id:
stop_browser(profile_id)
time.sleep(1)
delete_profile(profile_id)
if **name** == "**main**":
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
main()
сделай так, что после того, как мы авторизовались и переместились наjabka.to - мы освобождаем браузер от Playwright. Дальше я руками. чтобы капча работала