1

I would like to download a PDF in Python using Selenium WebDriver. However, for some reason I cannot select / click the download button. It might be due to the fact that the button is not focusable?

This is the button: enter image description here

<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="spinner-third" class="svg-inline--fa fa-spinner-third fa-w-16 fa-icon menubar-h-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z"></path></svg>

And here is my current code to reproduce:

from selenium import webdriver
import time

website = "https://onlinelibrary.wiley.com/doi/epdf/10.1111/jofi.12895"
driver = webdriver.Chrome()
driver.get(website)
driver.set_window_size(1024, 768)
time.sleep(4)
Guy
  • 34,831
  • 9
  • 31
  • 66
user27074
  • 515
  • 1
  • 3
  • 14

1 Answers1

1

As the the desired element is within an <iframe> so to invoke click() on the element you have to:

  • Induce WebDriverWait for the desired frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the desired element_to_be_clickable().
  • You can use either of the following Locator Strategies:

    • Using CSS_SELECTOR:

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe.rc-reader-frame")))
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "menu-button.download span"))).click()
      
    • Using XPATH:

      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[@class='rc-reader-frame']")))
      WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//menu-button[@class='download']//span[text()='PDF']"))).click()
      
    • Note : You have to add the following imports :

      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.common.by import By
      from selenium.webdriver.support import expected_conditions as EC
      
  • Browser snapshot:

download


Reference

You can find a couple of relevant discussions in:

DebanjanB
  • 118,661
  • 30
  • 168
  • 217
  • I had to edit the second line a bit, but then it worked! {WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//menu-button[@class='download']"))).click()} – user27074 Mar 08 '20 at 03:36
  • @user27074 I suspected that there might be some difference between the DOM rendered within my setup and the DOM you are seeing as there was a visual mismatch. But, I was sure the answer will take you closer. Glad to be able to help you out !!! – DebanjanB Mar 08 '20 at 18:09