Вопрос:

Selenium дает имя файла при загрузке

python file selenium download

14302 просмотра

5 ответа

0 Репутация автора

Я работаю со сценарием селена, где я пытаюсь загрузить файл Excel и дать ему конкретное имя. Это мой код:

Можно ли в любом случае дать файлу загружаемое имя?

Код:

#!/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
Автор: user3580316 Источник Размещён: 31.12.2015 02:53

Ответы (5)


8 плюса

2540 Репутация автора

Решение

Вы не можете указать имя файла загрузки через селен. Тем не менее, вы можете скачать файл, найти последний файл в загруженной папке и переименовать по своему усмотрению.

Примечание: заимствованные методы из поисков Google могут иметь ошибки. Но ты получил идею.

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)
Автор: parishodak Размещён: 31.12.2015 03:09

-1 плюса

218 Репутация автора

Вы можете скачать файл и назвать его одновременно, используя urlretrieve:

import urllib

url = browser.find_element_by_partial_link_text("Excel").get_attribute('href')
urllib.urlretrieve(url, "/choose/your/file_name.xlsx")
Автор: James Lemieux Размещён: 04.01.2016 12:35

2 плюса

556 Репутация автора

Есть кое-что, что я бы исправил для ответа @parishodak:

имя файла здесь будет возвращать только относительный путь (здесь имя файла), а не абсолютный путь.

Вот почему @FreshRamen получил следующую ошибку после:

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'

Есть правильный код:

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)
Автор: toshiro92 Размещён: 17.04.2016 04:16

2 плюса

174 Репутация автора

Надеюсь, этот фрагмент не так запутан. Это заняло у меня некоторое время, и это действительно полезно, потому что не было четкого ответа на эту проблему, только с этой библиотекой.

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))

Надеюсь, это спасет чей-то день, ура.

РЕДАКТИРОВАТЬ: Благодаря @Om Prakash редактирование моего кода, я вспомнил, что я не объяснил код все равно.

Использование max([])функции может привести к состоянию гонки, оставляя вас с пустым или поврежденным файлом (я знаю это по опыту). Вы хотите проверить, если файл полностью загружен в первую очередь. Это связано с тем, что селен не ждет завершения загрузки файла, поэтому при проверке последнего созданного файла в сгенерированном списке появится неполный файл, и он попытается переместить этот файл. И даже тогда вам лучше немного подождать, пока файл освободится от Firefox.

РЕДАКТИРОВАТЬ 2: больше кода

Меня спросили, достаточно ли 1 секунды времени, и в основном это так, но в случае, если вам нужно подождать больше, вы можете изменить приведенный выше код следующим образом:

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))
Автор: dmb Размещён: 10.11.2016 01:41

0 плюса

3852 Репутация автора

Вот еще одно простое решение, в котором вы можете подождать до завершения загрузки, а затем получить имя загруженного файла из загрузок Chrome.

# 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

После того, как вы нажмете на ссылку / кнопку загрузки, просто вызовите вышеуказанный метод.

 # 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)
Автор: supputuri Размещён: 12.06.2019 09:06
Вопросы из категории :
32x32