0

I want to save this file using Selenium. I'm able to click "save-as" with the following code:

driver = webdriver.Chrome(chrome_options=options, executable_path = chrome_driver_path)
driver.get('https://www.shs-conferences.org/articles/shsconf/pdf/2019/06/shsconf_m3e22019_03006.pdf')

ActionChains(driver).move_to_element(driver.find_element_by_xpath('//*[@id="plugin"]')).key_down(Keys.CONTROL).send_keys('s').key_up(Keys.CONTROL).perform()

However, I cannot get python to press the "save" bottom in the pop-up window. I have tried:

driver.find_elements_by_xpath("//*[contains(text(), 'Save')]").click()

and

ActionChains(driver).send_keys(u'\ue007').perform()

Anyone know how to click the "save" bottom?

Modvinden
  • 33
  • 2
  • 8
  • There are better ways to download pdf file than using selenium to do this. see answers here - https://stackoverflow.com/questions/24844729/download-pdf-using-urllib – Sureshmani Kalirajan Oct 17 '19 at 12:05
  • @Sureshmani that isn't what the user asked. If you're going to offer an alternative method, you should also outline how to do it in Selenium, and explain why it's not a good idea. – Glazbee Oct 17 '19 at 12:06
  • 1
    Possible duplicate of [How to control the download of files with Selenium + Python bindings in Chrome](https://stackoverflow.com/questions/40654358/how-to-control-the-download-of-files-with-selenium-python-bindings-in-chrome) – Glazbee Oct 17 '19 at 12:07

3 Answers3

5

UPDATE

While as said above by @Glazbee selenium cannot access OS dialog there is a work-around with pyautogui. Try the following if you do not want to set a default download folder in your chrome_options of your webdriver:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import pyautogui
import time

driver = webdriver.Chrome(chrome_options=options, executable_path = chrome_driver_path)
driver.get('https://www.shs-conferences.org/articles/shsconf/pdf/2019/06/shsconf_m3e22019_03006.pdf')

webdriver.ActionChains(driver).move_to_element(driver.find_element_by_xpath('//*[@id="plugin"]')).key_down(Keys.CONTROL).send_keys('s').key_up(Keys.CONTROL).perform()
time.sleep(1)
pyautogui.press('enter')
Community
  • 1
  • 1
Kostas Charitidis
  • 2,991
  • 1
  • 12
  • 23
  • 1
    It does not work - nothing happens when the code is executed – Modvinden Oct 17 '19 at 11:58
  • @Modvinden is that a pop-up to save a file? – Kostas Charitidis Oct 17 '19 at 12:02
  • 1
    This won't work. Chrome doesn't render the save dialogue to the page, it is instead passed from native code. As Selenium doesn't have access to the native binaries - Just the Javascript rendered to a page - It cannot access a save dialogue. – Glazbee Oct 17 '19 at 12:05
  • @Glazbee you're right I didn't get what he was trying to do before, I thought he just needed to press `enter`. There is a work around though. – Kostas Charitidis Oct 17 '19 at 12:14
  • Will your updated solution work on a headless browser? I know it was on the roadmap, but I didn't think it was released just yet – Glazbee Oct 17 '19 at 12:19
  • @Glazbee hmm that's a good observation though I cannot reproduce while when running the above headless does not find the `xpath` element provided. – Kostas Charitidis Oct 17 '19 at 12:24
  • pyautogui.press('enter') - working fine. thanks - @KostasCharitidis – Naresh Kumar Apr 05 '21 at 05:09
5

you can use the keyboard module in combination with selenium

import keyboard, time

keyboard.press(['ctrl', 's'])
time.sleep(1)
keyboard.press('enter')

This will let you save the file.

Bishnu
  • 99
  • 1
  • 7
  • this was really helpul. Thanks, i hope it works in headless mode – Carlost Jul 25 '22 at 06:09
  • Haven't tested in headless mode but it works well with UI. I am using `keyboard.press_and_release('ctrl+s')` instead as suggested [here](https://pypi.org/project/keyboard/) – Sanlok Lee Jan 29 '23 at 18:16
0

Edit: This answer has been reported to be outdated. I am not in a position to test this, please look into using solutions from other answers.

The reason this isn't working for you is that the save dialogue used by Chrome is not rendered as a web page. It's native code.

To get around this, you can use the selenium.webdriver.chrome.options.Options module. You will need to set a default file directory, otherwise, a prompt will appear. You can use a script like the following; You can find more information here. You can also find information on why experimental options are used here

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_experimental_option("prefs", {
  "download.default_directory": r"C:\Users\xxx\downloads\Test",
  "download.prompt_for_download": False,
  "download.directory_upgrade": True,
  "safebrowsing.enabled": True
})
Glazbee
  • 640
  • 5
  • 22
  • This doesn't work, the pop-up still appears. – Abhishek Rai Jun 03 '21 at 15:21
  • 1
    @AbhishekRai apologies for the delay in response. I no longer work with Selenium, but as of Oct 2019, this was working (Unfortunately I do not have the version numbers). – Glazbee Sep 15 '21 at 18:40