Reputation: 4973
I have this script that successfully downloads a file from a webpage, even headlessly thanks to this
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
# function to take care of downloading file
def enable_download_headless(browser,download_dir):
browser.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
params = {'cmd':'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
browser.execute("send_command", params)
# instantiate a chrome options object so you can set the size and headless preference
# some of these chrome options might be uncessary but I just used a boilerplate
# change the <path_to_download_default_directory> to whatever your default download folder is located
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("--window-size=1920x1080")
chrome_options.add_argument("--disable-notifications")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--verbose')
chrome_options.add_experimental_option("prefs", {
"download.default_directory": ".",
"download.prompt_for_download": False,
"download.directory_upgrade": True,
"safebrowsing_for_trusted_sources_enabled": False,
"safebrowsing.enabled": False
})
chrome_options.add_argument('--disable-gpu')
#chrome_options.add_argument('--disable-software-rasterizer')
# initialize driver object and change the <path_to_chrome_driver> depending on your directory where your chromedriver should be
driver = webdriver.Chrome(options=chrome_options)
# change the <path_to_place_downloaded_file> to your directory where you would like to place the downloaded file
download_dir = "."
# function to handle setting up headless download
enable_download_headless(driver, download_dir)
# get request to target the site selenium is active on
driver.get("https://www.thinkbroadband.com/download")
# initialize an object to the location on the html page and click on it to download
search_input = driver.find_element_by_css_selector('#main-col > div > div > div:nth-child(8) > p:nth-child(1) > a > img')
search_input.click()
#this won't work because the file isn't here yet
with zipfile.ZipFile('my_downloaded_file.zip', 'r') as zip_ref:
zip_ref.extractall('.')
file = open('my_downloaded_file')
for line in file:
print(line)
file.close()
I want to use the file I have just downloaded. Everything at the bottom after the button.click() is just an example - printing out the contents for instance. It would be even better if I didn't have to find the file by name - if I could just pass selenium an empty object or something along with a function to call when the download is complete where I can use the object. How can I do something like this?
Upvotes: 1
Views: 1194
Reputation: 47
This will check if "Show in Folder" is in the pages source, which will be there if a file has been downloaded. Useful for one file, could be modified to see how many times it exists and thus check for multiple files.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.headless = True
with webdriver.Chrome(options=options) as b:
# your code here
b.execute_script("window.open('');")
b.switch_to.window(b.window_handles[1])
b.get('chrome://downloads/')
x = b.page_source
if "Show in folder" in x:
print("Yes")
else:
print("No")
Upvotes: 1