Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downloading with chrome headless and selenium

I'm using python-selenium and Chrome 59 and trying to automate a simple download sequence. When I launch the browser normally, the download works, but when I do so in headless mode, the download doesn't work.

# Headless implementation from selenium import webdriver  chromeOptions = webdriver.ChromeOptions() chromeOptions.add_argument("headless")  driver = webdriver.Chrome(chrome_options=chromeOptions)  driver.get('https://www.mockaroo.com/') driver.find_element_by_id('download').click() # ^^^ Download doesn't start 

# Normal Mode from selenium import webdriver  driver = webdriver.Chrome()  driver.get('https://www.mockaroo.com/') driver.find_element_by_id('download').click() # ^^^ Download works normally 

I've even tried adding a default path:

prefs = {"download.default_directory" : "/Users/Chetan/Desktop/"} chromeOptions.add_argument("headless") chromeOptions.add_experimental_option("prefs",prefs) 

Adding a default path works in the normal implementation, but the same problem persists in the headless version.

How do I get the download to start in headless mode?

like image 304
TheChetan Avatar asked Aug 11 '17 09:08

TheChetan


People also ask

Can you download files on headless Chrome?

Now the, the good news is Chromium team have officially announced the arrival of the functionality Downloading file through Headless Chromium .

Is headless Chrome faster Selenium?

Headless Browsers are Faster than Real Browsers But you will typically see a 2x to 15x faster performance when using a headless browser.

How do I run Selenium headless in Chrome?

You can run Google Chrome in headless mode simply by setting the headless property of the chromeOptions object to True. Or, you can use the add_argument() method of the chromeOptions object to add the –headless command-line argument to run Google Chrome in headless mode using the Selenium Chrome web driver.

How do I run a Chrome headless driver?

How to run Chrome in headless mode. In order to run your tests in headless mode, you will need to use the ChromeOptions as follows. ChromeOptions options = new ChromeOptions(); options. addArguments("--headless");


2 Answers

Yes, it's a "feature", for security. As mentioned before here is the bug discussion: https://bugs.chromium.org/p/chromium/issues/detail?id=696481

Support was added in chrome version 62.0.3196.0 or above to enable downloading.

Here is a python implementation. I had to add the command to the chromedriver commands. I will try to submit a PR so it is included in the library in the future.

def enable_download_in_headless_chrome(self, driver, download_dir):     # add missing support for chrome "send_command"  to selenium webdriver     driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')      params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}     command_result = driver.execute("send_command", params) 

For reference here is a little repo to demonstrate how to use this: https://github.com/shawnbutton/PythonHeadlessChrome

update 2020-05-01 There have been comments saying this is not working anymore. Given this patch is now over a year old it's quite possible they have changed the underlying library.

like image 163
Shawn Button Avatar answered Nov 05 '22 13:11

Shawn Button


Here's a working example for Python based on Shawn Button's answer. I've tested this with Chromium 68.0.3440.75 & chromedriver 2.38

from selenium import webdriver from selenium.webdriver.chrome.options import Options  chrome_options = Options() chrome_options.add_experimental_option("prefs", {   "download.default_directory": "/path/to/download/dir",   "download.prompt_for_download": False, })  chrome_options.add_argument("--headless") driver = webdriver.Chrome(chrome_options=chrome_options)  driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command') params = {'cmd': 'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': "/path/to/download/dir"}} command_result = driver.execute("send_command", params)  driver.get('http://download-page.url/') driver.find_element_by_css_selector("#download_link").click() 
like image 26
Fayçal Avatar answered Nov 05 '22 12:11

Fayçal