Naming a file when downloading with Selenium Webdriver
Question:
I see that you can set where to download a file to through Webdriver, as follows:
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir",getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk","text/csv")
browser = webdriver.Firefox(firefox_profile=fp)
But, I was wondering if there is a similar way to give the file a name when it is downloaded? Preferably, probably not something that is associated with the profile, as I will be downloading ~6000 files through one browser instance, and do not want to have to reinitiate the driver for each download.
Answers:
I do not know if there is a pure Selenium handler for this, but here is what I have done when I needed to do something with the downloaded file.
-
Set a loop that polls your download directory for the latest file that does not have a .part
extension (this indicates a partial download and would occasionally trip things up if not accounted for. Put a timer on this to ensure that you don’t go into an infinite loop in the case of timeout/other error that causes the download not to complete. I used the output of the ls -t <dirname>
command in Linux (my old code uses commands
, which is deprecated so I won’t show it here 🙂 ) and got the first file by using
# result = output of ls -t
result = result.split('n')[1].split(' ')[-1]
-
If the while
loop exits successfully, the topmost file in the directory will be your file, which you can then modify using os.rename
(or anything else you like).
Probably not the answer you were looking for, but hopefully it points you in the right direction.
I would suggest a little bit strange way: do not download files with the use of Selenium if possible.
I mean get the file URL and use urllib
library to download the file and save it to disk in a ‘manual’ way. The issue is that selenium doesn’t have a tool to handle Windows dialogs, such as ‘save as’ dialog. I’m not sure, but I doubt that it can handle any OS dialogs at all, please correct me I’m wrong. 🙂
Here’s a tiny example:
import urllib
urllib.urlretrieve( "http://www.yourhost.com/yourfile.ext", "your-file-name.ext")
The only job for us here is to make sure that we handle all the urllib Exceptions. Please see http://docs.python.org/2/library/urllib.html#urllib.urlretrieve for more info.
Solution with code as suggested by the selected answer. Rename the file after each one is downloaded.
import os
os.chdir(SAVE_TO_DIRECTORY)
files = filter(os.path.isfile, os.listdir(SAVE_TO_DIRECTORY))
files = [os.path.join(SAVE_TO_DIRECTORY, f) for f in files] # add path to each file
files.sort(key=lambda x: os.path.getmtime(x))
newest_file = files[-1]
os.rename(newest_file, docName + ".pdf")
This answer was posted as an edit to the question naming a file when downloading with Selenium Webdriver by the OP user1253952 under CC BY-SA 3.0.
I see that you can set where to download a file to through Webdriver, as follows:
fp = webdriver.FirefoxProfile()
fp.set_preference("browser.download.folderList",2)
fp.set_preference("browser.download.manager.showWhenStarting",False)
fp.set_preference("browser.download.dir",getcwd())
fp.set_preference("browser.helperApps.neverAsk.saveToDisk","text/csv")
browser = webdriver.Firefox(firefox_profile=fp)
But, I was wondering if there is a similar way to give the file a name when it is downloaded? Preferably, probably not something that is associated with the profile, as I will be downloading ~6000 files through one browser instance, and do not want to have to reinitiate the driver for each download.
I do not know if there is a pure Selenium handler for this, but here is what I have done when I needed to do something with the downloaded file.
-
Set a loop that polls your download directory for the latest file that does not have a
.part
extension (this indicates a partial download and would occasionally trip things up if not accounted for. Put a timer on this to ensure that you don’t go into an infinite loop in the case of timeout/other error that causes the download not to complete. I used the output of thels -t <dirname>
command in Linux (my old code usescommands
, which is deprecated so I won’t show it here 🙂 ) and got the first file by using# result = output of ls -t result = result.split('n')[1].split(' ')[-1]
-
If the
while
loop exits successfully, the topmost file in the directory will be your file, which you can then modify usingos.rename
(or anything else you like).
Probably not the answer you were looking for, but hopefully it points you in the right direction.
I would suggest a little bit strange way: do not download files with the use of Selenium if possible.
I mean get the file URL and use urllib
library to download the file and save it to disk in a ‘manual’ way. The issue is that selenium doesn’t have a tool to handle Windows dialogs, such as ‘save as’ dialog. I’m not sure, but I doubt that it can handle any OS dialogs at all, please correct me I’m wrong. 🙂
Here’s a tiny example:
import urllib
urllib.urlretrieve( "http://www.yourhost.com/yourfile.ext", "your-file-name.ext")
The only job for us here is to make sure that we handle all the urllib Exceptions. Please see http://docs.python.org/2/library/urllib.html#urllib.urlretrieve for more info.
Solution with code as suggested by the selected answer. Rename the file after each one is downloaded.
import os
os.chdir(SAVE_TO_DIRECTORY)
files = filter(os.path.isfile, os.listdir(SAVE_TO_DIRECTORY))
files = [os.path.join(SAVE_TO_DIRECTORY, f) for f in files] # add path to each file
files.sort(key=lambda x: os.path.getmtime(x))
newest_file = files[-1]
os.rename(newest_file, docName + ".pdf")
This answer was posted as an edit to the question naming a file when downloading with Selenium Webdriver by the OP user1253952 under CC BY-SA 3.0.