Home > Software design >  how to print a PDF document using selenium python?
how to print a PDF document using selenium python?

Time:08-16

I need to print a PDF file after having "downloaded" it using a selenium script. The issue is that it opens in a pop up window, however selenium should be able to handle that. This is the source code of the toolbar i want to interact with:

<div id="toolbar"><div id="start"><cr-icon-button id="sidenavToggle" iron-icon="cr20:menu" title="Menu" aria-label="Menu" aria-expanded="true" aria-disabled="false" role="button" tabindex="0"></cr-icon-button><span id="title">rdlComprobanteJubilados</span></div><div id="center"><viewer-page-selector style="--page-length-digits:1;"></viewer-page-selector><span ></span><span id="zoom-controls"><cr-icon-button iron-icon="pdf:remove" title="Zoom out" aria-label="Zoom out" aria-disabled="false" role="button" tabindex="0"></cr-icon-button><input type="text" value="100%" aria-label="Zoom level"><cr-icon-button iron-icon="pdf:add" title="Zoom in" aria-label="Zoom in" aria-disabled="false" role="button" tabindex="0"></cr-icon-button></span><span ></span><cr-icon-button id="fit" aria-label="Fit to page" title="Fit to page" aria-disabled="false" role="button" tabindex="0" iron-icon="pdf:fit-to-height"></cr-icon-button><cr-icon-button iron-icon="pdf:rotate-left" dir="ltr" aria-label="Rotate counterclockwise" title="Rotate counterclockwise" aria-disabled="false" role="button" tabindex="0"></cr-icon-button></div><div id="end"><viewer-download-controls id="downloads"></viewer-download-controls><cr-icon-button id="print" iron-icon="cr:print" title="Print" aria-label="Print" aria-disabled="false" role="button" tabindex="0"></cr-icon-button><cr-icon-button id="more" iron-icon="cr:more-vert" title="More actions" aria-label="More actions" aria-disabled="false" role="button" tabindex="0"></cr-icon-button></div></div>

although the full source code is here.

I want to interact with this element:

<cr-icon-button id="print" iron-icon="cr:print" title="Print" aria-label="Print" aria-disabled="false" role="button" tabindex="0"></cr-icon-button>

my current approach is this:

for handle in driver.window_handles:
    if driver.current_window_handle!=handle:
        driver.switch_to.window(handle)
        print("changed")
pbutton=filebutton=driver.find_element(By.ID,"print")
pbutton.click()
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="print"]')))).select_by_index(2)
print("pass")

which yields this error:

NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="print"]"}
  (Session info: chrome=104.0.5112.81)
Stacktrace:
Backtrace:
    Ordinal0 [0x00E35FD3 2187219]
    Ordinal0 [0x00DCE6D1 1763025]
    Ordinal0 [0x00CE3E78 802424]
    Ordinal0 [0x00D11C10 990224]
    Ordinal0 [0x00D11EAB 990891]
    Ordinal0 [0x00D3EC92 1174674]
    Ordinal0 [0x00D2CBD4 1100756]
    Ordinal0 [0x00D3CFC2 1167298]
    Ordinal0 [0x00D2C9A6 1100198]
    Ordinal0 [0x00D06F80 946048]
    Ordinal0 [0x00D07E76 949878]
    GetHandleVerifier [0x010D90C2 2721218]
    GetHandleVerifier [0x010CAAF0 2662384]
    GetHandleVerifier [0x00EC137A 526458]
    GetHandleVerifier [0x00EC0416 522518]
    Ordinal0 [0x00DD4EAB 1789611]
    Ordinal0 [0x00DD97A8 1808296]
    Ordinal0 [0x00DD9895 1808533]
    Ordinal0 [0x00DE26C1 1844929]
    BaseThreadInitThunk [0x75906739 25]
    RtlGetFullPathName_UEx [0x770390AF 1215]
    RtlGetFullPathName_UEx [0x7703907D 1165]

i´m running Python 3.9.7 and Selenium 4.3.0 and i work with Jupyter Notebooks installed with Anaconda and the browser used is Google Chrome Versión 104.0.5112.81 (Build oficial) (64 bits) I need the solution to work as a standalone script and preferably OS agnostic although if that´s not possible it would be enough to have it run in Linux Mint

CodePudding user response:

To click on the desired element you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "cr-icon-button#print[title='Print'][aria-label='Print']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//cr-icon-button[@id='print' and @title='Print'][@aria-label='Print']"))).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
    

CodePudding user response:

I finally found a way to solve it WITHOUT interacting with the PDF viewer. i used the option module:

from selenium.webdriver.chrome.options import Options
DRIVER_PATH = r"C:\Users\HP\Downloads\chromedriver_win32\chromedriver.exe"
chrome_options = Options()
chrome_options.add_experimental_option('prefs', {
"download.default_directory": r"C:\Users\HP\Desktop\test downloads", #Change default directory for downloads
"download.prompt_for_download": False, #To auto download the file
"download.directory_upgrade": True,
"plugins.always_open_pdf_externally": True #It will not show PDF directly in chrome
})

driver = webdriver.Chrome(executable_path=DRIVER_PATH,options = chrome_options)
driver.implicitly_wait(60)
  • Related