[Python] Playwright how to detect download events [closed]

Discussão em 'Python' iniciado por Stack, Maio 9, 2025.

  1. Stack

    Stack Membro Participativo

    I want to download a report from a website using playwright, the structure of the website is like this:

    1. Fill in input and click download button
    2. Redirect to another page (with a progress bar/ spinner) while waiting for download to finish
    3. The time taken to download will depends on the size of the report

    The problem I encountered is:

    1. I need to download a list of report with different input values
    2. For some input values, there is no report, however, the line

    $ if download_info:

    return true even if there is nothing downloaded (I can see from the chromium browser

    1. therefore, the next line

    $download =download_info.value

    will take forever to run until the end of the timeour

    Here is my code:

    try:
    with page.expect_download(timeout=6000000) as download_info:
    print("Step 1: Preparing to click download button")
    button.click()
    print("Step 2: Clicked Download Report button")

    print("Step 3: Waiting for progress spinner to appear...")
    page.wait_for_selector('.mat-progress-spinner', timeout=10000)
    print("Step 4: Progress spinner detected.")

    print("Step 5: Waiting for the spinner to disappear or stop spinning...")
    page.evaluate("console.log('Step 5: Waiting for spinner to disappear')")
    start_time = datetime.datetime.now()
    page.wait_for_function(
    """async () => {
    console.log("Inside wait_for_function: Checking spinner...");

    // Function to pause for a specified time (1000ms)
    function delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
    }

    while (true) {
    const spinner = document.querySelector('.mat-progress-spinner');
    if (!spinner) {
    console.log("Spinner not found.");
    return true;
    }
    const style = window.getComputedStyle(spinner);
    console.log("Spinner visibility:", style.display, style.visibility);
    if (style.display === 'none' || style.visibility === 'hidden' || spinner.getBoundingClientRect().height === 0) {
    console.log("Spinner disappeared or hidden.");
    return true;
    }

    // Pause for 500 milliseconds before the next check
    await delay(500);
    }
    }""",
    timeout=6000000 # 5 minutes
    )
    end_time = datetime.datetime.now()
    duration = end_time - start_time
    print(f"time taken = {duration}")
    print("Step 6: Spinner stopped or disappeared.")
    page.evaluate("console.log('Step 6: Spinner stopped or disappeared')")

    print("Step 7: Waiting briefly to see if download starts...")

    page.wait_for_timeout(1000)

    if download_info:
    print("download found!!!!")
    print("Step 8: Waiting for download event...")
    download = download_info.value
    print("Step 9: Download event captured")

    path = download.path()
    if path and os.path.exists(path):
    df = pd.read_excel(path)
    print("Step 10: File downloaded and read successfully.")
    else:
    print('Error: download path not found')
    return
    time.sleep(0.5)
    if df is not None:
    df = df['csoStatus']
    return df
    else:
    print("Step 000: No download event occurred after spinner stopped.")
    return None

    except Exception as e:
    print(f"Error during download: {e}")
    return None



    The method I have tried:

    1. Conccurent futures, but it does not work because I am using playwright
    2. Try to terminate the chunk started with 'if download_info:' but it always stuck at the assignment

    I have updated the code to the latest version, thank you

    Continue reading...

Compartilhe esta Página