import json import time from playwright.sync_api import sync_playwright def analyze_gwt_response(response_text): candidates = [] try: if response_text.startswith("//OK"): response_text = response_text[4:] data = json.loads(response_text) if isinstance(data, list): for i in range(len(data) - 2): val1 = data[i] val2 = data[i+2] if (isinstance(val1, (int, float)) and isinstance(val2, (int, float))): if abs(val1) > 100000 and abs(val2) > 100000: candidates.append((val1, val2)) if len(candidates) > 5: break except: pass return candidates def fetch_live_data(map_url): """ Uses a real browser to fetch data AND capture the raw request details. """ print(f"--- Browser Fetch: {map_url} ---") data_result = None captured_headers = None captured_cookies = None captured_body = None # <--- New: Capture raw body with sync_playwright() as p: browser = p.chromium.launch(headless=True, args=['--disable-blink-features=AutomationControlled']) context = browser.new_context( user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' ) page = context.new_page() def handle_request(request): nonlocal captured_headers, captured_body if ".rpc" in request.url and request.method == "POST": # Capture the request details blindly before we even know if it works if "getCombinedOutageDetails" in request.post_data or "getOutages" in request.post_data: captured_headers = request.headers captured_body = request.post_data def handle_response(response): nonlocal data_result if ".rpc" in response.url and response.request.method == "POST": try: if "getCombinedOutageDetails" in response.request.post_data or "getOutages" in response.request.post_data: text = response.text() if text.startswith("//OK"): data_result = json.loads(text[4:]) print(" [+] Captured Data via Browser") except: pass page.on("request", handle_request) page.on("response", handle_response) try: page.goto(map_url, wait_until="networkidle", timeout=60000) for _ in range(10): if data_result: break time.sleep(1) captured_cookies = context.cookies() except Exception as e: print(f"Browser Fetch Error: {e}") finally: browser.close() return data_result, captured_headers, captured_cookies, captured_body def get_fresh_config(map_url): data, headers, cookies, body = fetch_live_data(map_url) if headers and body: # Minimal cleaning: Only remove headers that 'requests' MUST generate itself # This keeps all custom NISC/GWT headers safe. forbidden = {'content-length', 'host', 'connection', 'cookie', 'accept-encoding'} clean_headers = {k: v for k, v in headers.items() if k.lower() not in forbidden} return { 'headers': clean_headers, 'body': body, # Save exact body 'url': headers.get('url', map_url.replace('.html', '') + '/GWT.rpc'), # Best guess URL if missing 'cookies': cookies, 'user_agent': headers.get('user-agent') } return None if __name__ == "__main__": url = input("Enter Map URL: ") res = get_fresh_config(url) if res: print("Success! Captured Body length:", len(res['body'])) print("Captured Headers:", res['headers'].keys())