Selenium (Python) - waiting for a download process to complete using Chrome web driver

后端 未结 9 1184

I\'m using selenium and python via chromewebdriver (windows) in order to automate a task of downloading large amount of files from different pages. My code works, but the so

9条回答
  •  天涯浪人
    2020-12-04 19:08

    There are issues with opening chrome://downloads/ when running Chrome in headless mode.

    The following function uses a composite approach that works whether the mode is headless or not, choosing the better approach available in each mode.

    It assumes that the caller clears all files downloaded at file_download_path after each call to this function.

    import os
    import logging
    from selenium.webdriver.support.ui import WebDriverWait
    
    def wait_for_downloads(driver, file_download_path, headless=False, num_files=1):
        max_delay = 60
        interval_delay = 0.5
        if headless:
            total_delay = 0
            done = False
            while not done and total_delay < max_delay:
                files = os.listdir(file_download_path)
                # Remove system files if present: Mac adds the .DS_Store file
                if '.DS_Store' in files:
                    files.remove('.DS_Store')
                if len(files) == num_files and not [f for f in files if f.endswith('.crdownload')]:
                    done = True
                else:
                    total_delay += interval_delay
                    time.sleep(interval_delay)
            if not done:
                logging.error("File(s) couldn't be downloaded")
        else:
            def all_downloads_completed(driver, num_files):
                return driver.execute_script("""
                    var items = document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList').items;
                    var i;
                    var done = false;
                    var count = 0;
                    for (i = 0; i < items.length; i++) {
                        if (items[i].state === 'COMPLETE') {count++;}
                    }
                    if (count === %d) {done = true;}
                    return done;
                    """ % (num_files))
    
            driver.execute_script("window.open();")
            driver.switch_to_window(driver.window_handles[1])
            driver.get('chrome://downloads/')
            # Wait for downloads to complete
            WebDriverWait(driver, max_delay, interval_delay).until(lambda d: all_downloads_completed(d, num_files))
            # Clear all downloads from chrome://downloads/
            driver.execute_script("""
                document.querySelector('downloads-manager').shadowRoot
                .querySelector('#toolbar').shadowRoot
                .querySelector('#moreActionsMenu')
                .querySelector('button.clear-all').click()
                """)
            driver.close()
            driver.switch_to_window(driver.window_handles[0])
    

提交回复
热议问题