python file selenium download

python - Selenium da el nombre del archivo al descargar



file download (5)

Aquí hay otra solución simple, donde puede esperar hasta que se complete la descarga y luego obtener el nombre del archivo descargado de las descargas de Chrome.

Cromo:

# method to get the downloaded file name def getDownLoadedFileName(waitTime): driver.execute_script("window.open()") # switch to new tab driver.switch_to.window(driver.window_handles[-1]) # navigate to chrome downloads driver.get(''chrome://downloads'') # define the endTime endTime = time.time()+waitTime while True: try: # get downloaded percentage downloadPercentage = driver.execute_script( "return document.querySelector(''downloads-manager'').shadowRoot.querySelector(''#downloadsList downloads-item'').shadowRoot.querySelector(''#progress'').value") # check if downloadPercentage is 100 (otherwise the script will keep waiting) if downloadPercentage == 100: # return the file name once the download is completed return driver.execute_script("return document.querySelector(''downloads-manager'').shadowRoot.querySelector(''#downloadsList downloads-item'').shadowRoot.querySelector(''div#content #file-link'').text") except: pass time.sleep(1) if time.time() > endTime: break

Firefox

def getDownLoadedFileName(waitTime): driver.execute_script("window.open()") WebDriverWait(driver,10).until(EC.new_window_is_opened) driver.switch_to.window(driver.window_handles[-1]) driver.get("about:downloads") endTime = time.time()+waitTime while True: try: fileName = driver.execute_script("return document.querySelector(''#contentAreaDownloadsView .downloadMainArea .downloadContainer description:nth-of-type(1)'').value") if fileName: return fileName except: pass time.sleep(1) if time.time() > endTime: break

Una vez que haga clic en el enlace / botón de descarga, simplemente llame al método anterior.

# click on download link browser.find_element_by_partial_link_text("Excel").click() # get the downloaded file name latestDownloadedFileName = getDownLoadedFileName(180) #waiting 3 minutes to complete the download print(latestDownloadedFileName)

JAVA + Chrome:

Aquí está el método en Java.

public String waitUntilDonwloadCompleted(WebDriver driver) throws InterruptedException { // Store the current window handle String mainWindow = driver.getWindowHandle(); // open a new tab JavascriptExecutor js = (JavascriptExecutor)driver; js.executeScript("window.open()"); // switch to new tab // Switch to new window opened for(String winHandle : driver.getWindowHandles()){ driver.switchTo().window(winHandle); } // navigate to chrome downloads driver.get("chrome://downloads"); JavascriptExecutor js1 = (JavascriptExecutor)driver; // wait until the file is downloaded Long percentage = (long) 0; while ( percentage!= 100) { try { percentage = (Long) js1.executeScript("return document.querySelector(''downloads-manager'').shadowRoot.querySelector(''#downloadsList downloads-item'').shadowRoot.querySelector(''#progress'').value"); //System.out.println(percentage); }catch (Exception e) { // Nothing to do just wait } Thread.sleep(1000); } // get the latest downloaded file name String fileName = (String) js1.executeScript("return document.querySelector(''downloads-manager'').shadowRoot.querySelector(''#downloadsList downloads-item'').shadowRoot.querySelector(''div#content #file-link'').text"); // get the latest downloaded file url String sourceURL = (String) js1.executeScript("return document.querySelector(''downloads-manager'').shadowRoot.querySelector(''#downloadsList downloads-item'').shadowRoot.querySelector(''div#content #file-link'').href"); // file downloaded location String donwloadedAt = (String) js1.executeScript("return document.querySelector(''downloads-manager'').shadowRoot.querySelector(''#downloadsList downloads-item'').shadowRoot.querySelector(''div.is-active.focus-row-active #file-icon-wrapper img'').src"); System.out.println("Download deatils"); System.out.println("File Name :-" + fileName); System.out.println("Donwloaded path :- " + donwloadedAt); System.out.println("Downloaded from url :- " + sourceURL); // print the details System.out.println(fileName); System.out.println(sourceURL); // close the downloads tab2 driver.close(); // switch back to main window driver.switchTo().window(mainWindow); return fileName; }

Así es como llamar a esto en su script java.

// download triggering step downloadExe.click(); // now waituntil download finish and then get file name System.out.println(waitUntilDonwloadCompleted(driver));

Salida:

Descargar detalles

Nombre de archivo: -RubyMine-2019.1.2 (7) .exe

Ruta descargada: - Chrome: //fileicon/C%3A%5CUsers%5Csupputuri%5CDownloads%5CRubyMine-2019.1.2%20 (7) .exe? Scale = 1.25x

Descargado desde url: - https://download-cf.jetbrains.com/ruby/RubyMine-2019.1.2.exe

RubyMine-2019.1.2 (7) .exe

Estoy trabajando con un script de selenio donde estoy tratando de descargar un archivo de Excel y darle un nombre específico. Este es mi código:

¿Hay alguna forma de darle un nombre específico al archivo que se está descargando?

Código:

#!/usr/bin/python from selenium import webdriver from selenium.webdriver.firefox.firefox_profile import FirefoxProfile profile = FirefoxProfile() profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/plain, application/vnd.ms-excel, text/csv, text/comma-separated-values, application/octet-stream") profile.set_preference("browser.download.dir", "C://Downloads" ) browser = webdriver.Firefox(firefox_profile=profile) browser.get(''https://test.com/'') browser.find_element_by_partial_link_text("Excel").click() # Download file


Espero que este fragmento no sea tan confuso. Me tomó un tiempo crear esto y es realmente útil, porque no ha habido una respuesta clara a este problema, solo con esta biblioteca.

import os import time def tiny_file_rename(newname, folder_of_download): filename = max([f for f in os.listdir(folder_of_download)], key=lambda xa : os.path.getctime(os.path.join(folder_of_download,xa))) if ''.part'' in filename: time.sleep(1) os.rename(os.path.join(folder_of_download, filename), os.path.join(folder_of_download, newname)) else: os.rename(os.path.join(folder_of_download, filename),os.path.join(folder_of_download,newname))

Espero que esto salve el día de alguien, saludos.

EDITAR: Gracias a @Om Prakash que editó mi código, me hizo recordar que no expliqué el código sin embargo.

El uso de la función max([]) podría provocar una condición de carrera, dejándolo con un archivo vacío o dañado (lo sé por experiencia). En primer lugar, desea verificar si el archivo está completamente descargado. Esto se debe al hecho de que el selenio no espera a que se complete la descarga del archivo, por lo que cuando verifique el último archivo creado, aparecerá un archivo incompleto en su lista generada e intentará mover ese archivo. E incluso entonces, es mejor esperar un poco para que el archivo esté libre de Firefox.

EDIT 2: más código

Me preguntaron si 1 segundo era suficiente y, sobre todo, lo es, pero en caso de que necesite esperar más de eso, puede cambiar el código anterior a esto:

import os import time def tiny_file_rename(newname, folder_of_download, time_to_wait=60): time_counter = 0 filename = max([f for f in os.listdir(folder_of_download)], key=lambda xa : os.path.getctime(os.path.join(folder_of_download,xa))) while ''.part'' in filename: time.sleep(1) time_counter += 1 if time_counter > time_to_wait: raise Exception(''Waited too long for file to download'') filename = max([f for f in os.listdir(folder_of_download)], key=lambda xa : os.path.getctime(os.path.join(folder_of_download,xa))) os.rename(os.path.join(folder_of_download, filename), os.path.join(folder_of_download, newname))


Hay algo que corregiría para la respuesta de @parishodak:

el nombre de archivo aquí solo devolverá la ruta relativa (aquí el nombre del archivo), no la ruta absoluta.

Es por eso que @FreshRamen recibió el siguiente error después:

File "/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/‌​python2.7/genericpath.py", line 72, in getctime return os.stat(filename).st_ctime OSError: [Errno 2] No such file or directory: ''.localized''

Existe el código correcto:

import os import shutil filepath = ''c:/downloads'' filename = max([filepath +"/"+ f for f in os.listdir(filepath)], key=os.path.getctime) shutil.move(os.path.join(dirpath,filename),newfilename)


No puede especificar el nombre del archivo de descarga a través de selenio. Sin embargo, puede descargar el archivo, encontrar el último archivo en la carpeta descargada y cambiar el nombre como desee.

Nota: los métodos prestados de las búsquedas de Google pueden tener errores. Pero se entiende la idea.

import os import shutil filename = max([f for f in os.listdir(''c:/downloads'')], key=os.path.getctime) shutil.move(os.path.join(dirpath,filename),newfilename)


Puede descargar el archivo y nombrarlo al mismo tiempo usando urlretrieve :

import urllib url = browser.find_element_by_partial_link_text("Excel").get_attribute(''href'') urllib.urlretrieve(url, "/choose/your/file_name.xlsx")