import asyncio from playwright.async_api import async_playwright UU_EMAIL = "email@gmail.com" UU_PASSWORD = "password" async def download_uu_bill_live(): async with async_playwright() as p: # Opens visible browser with 1.5 second step delay browser = await p.chromium.launch(headless=False, slow_mo=1500) page = await browser.new_page() print("Opening United Utilities homepage...") await page.goto("https://unitedutilities.com") # Handle cookie banner (confirmed working) try: await page.click("button:has-text('Accept All')", timeout=5000) print("Cookies accepted.") except Exception: pass # NEW STEP: Click the header login button based on your HTML code print("Clicking 'LOG IN / REGISTER' button in the header...") await page.click("a.c-navigation__actions-btn:has-text('LOG IN / REGISTER')") # Wait for the login portal page to fully transition and load print("Waiting for login portal page to load...") await page.wait_for_url("https://myaccount.unitedutilities.com/**", timeout=15000) print("Typing credentials live...") # Targets the unique ID 'login-email' from your HTML snippet await page.fill("#login-email", UU_EMAIL) # Targets the likely matching password ID structure await page.fill("#PasswordMasking", UU_PASSWORD) print("Clicking submit login form...") await page.click("#login-btn") print("Waiting for dashboard to load...") await page.wait_for_url("https://myaccount.unitedutilities.com/Secure/Dashboard", timeout=30000) print("Navigating to billing section...") await page.click("text=View bills and payments") print("Clicking 'View statement' button...") await page.click("a[href*='type=viewStatement']") # NEW STEP: Wait for the dynamic bills table to finish loading print("Waiting for bills table to load...") await page.wait_for_selector("table#viewBill tbody tr") # Trigger and catch the file download pipeline async with page.expect_download() as download_info: print("Clicking the newest bill download link in the table...") # Targets the very first row's download link inside the table body await page.locator("table#viewBill tbody tr").first.locator("a[href*='DownloadBill.aspx']").click() download = await download_info.value save_path = "./united_utilities_bill.pdf" await download.save_as(save_path) print(f"Success! Newest bill saved to {save_path}") print("Finishing up, closing browser in 5 seconds...") await asyncio.sleep(5) await browser.close() asyncio.run(download_uu_bill_live())