web-dev-qa-db-fra.com

Selenium (Python): attente de la fin du processus de téléchargement à l'aide du pilote Web Chrome.

J'utilise Selenium et python via chromewebdriver (windows) afin d'automatiser le téléchargement de nombreux fichiers à partir de différentes pages. Mon code fonctionne, mais la solution est loin d'être idéale: la fonction ci-dessous permet de cliquer sur le bouton de site Web qui lance une fonction de script Java générant un fichier PDF, puis le télécharge.

J'ai dû utiliser une attente statique afin d'attendre que le téléchargement soit terminé (moche). Je ne peux pas vérifier le système de fichiers afin de vérifier quand le téléchargement est terminé puisque j'utilise plusieurs threads (téléchargement de nombreux fichiers à partir de pages différentes à la fois) et aussi le nom des fichiers est généré dynamiquement dans le site lui-même.

Mon code:

def file_download(num, drivervar):
Counter += 1
    try:
        drivervar.get(url[num])
        download_button = WebDriverWait(drivervar, 20).until(EC.element_to_be_clickable((By.ID, 'download button ID')))
        download_button.click()
        time.sleep(10) 
    except TimeoutException: # Retry once
        print('Timeout in thread number: ' + str(num) + ', retrying...')
..... 

Est-il possible de déterminer l'achèvement du téléchargement dans Webdriver? Je veux éviter d'utiliser time.sleep (x).

Merci beaucoup.

4
BlackMamba

Vous pouvez obtenir le statut de chaque téléchargement en naviguant chrome://downloads/ avec le pilote.

Pour attendre que tous les téléchargements se terminent et pour lister tous les chemins:

def every_downloads_chrome(driver):
    if not driver.current_url.startswith("chrome://downloads"):
        driver.get("chrome://downloads/")
    return driver.execute_script("""
        var items = downloads.Manager.get().items_;
        if (items.every(e => e.state === "COMPLETE"))
            return items.map(e => e.file_url);
        """)


# waits for all the files to be completed and returns the paths
paths = WebDriverWait(driver, 120, 1).until(every_downloads_chrome)
print(paths)
7
Florent B.

J'ai eu le même problème et j'ai trouvé une solution. Vous pouvez vérifier si un fichier .crdownload se trouve dans votre dossier de téléchargement. S'il existe 0 instances d'un fichier avec l'extension .crdownload dans le dossier de téléchargement, tous vos téléchargements sont terminés. Cela ne fonctionne que pour le chrome et le chrome, je pense.

def downloads_done():
    for i in os.listdir("data/"):
        if ".crdownload" in i:
            time.sleep(0.5)
            downloads_done()

Chaque fois que vous appelez downloads_done (), il se mettra en boucle jusqu'à ce que tous les téléchargements soient terminés. Si vous téléchargez des fichiers volumineux tels que 80 gigaoctets, je vous le déconseille car la fonction peut atteindre une profondeur de récursivité maximale.

1
Walter Randomness

Lors de l'utilisation de l'automatisation des tests, il est essentiel que les développeurs rendent le logiciel testable. Il est de votre devoir de vérifier le logiciel associé à la testabilité, ce qui signifie que vous devez demander un spinner ou une simple balise HTML indiquant le moment où le téléchargement est terminé.

Dans un cas comme le vôtre, où vous ne pouvez pas le vérifier dans l'interface utilisateur ni dans le système, c'est la meilleure façon de le résoudre.

0
Anand