【问题标题】:How to handle Firefox print dialog box in Selenium如何在 Selenium 中处理 Firefox 打印对话框
【发布时间】:2021-08-25 00:28:49
【问题描述】:

我有以下代码:

from selenium.webdriver import Firefox
from selenium.webdriver.common.keys import Keys
url = 'https://finance.yahoo.com/'
driver_path = 'geckodriver.exe'

browser = Firefox(executable_path = driver_path)
browser.get(url)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
profile.set_preference("browser.helperApps.neverAsk.openFile", "application/pdf")
search_field_id = 'yfin-usr-qry'

element_search_field = browser.find_element_by_id(search_field_id)
element_search_field.clear()
element_search_field.send_keys('TSLA')
element_search_field.send_keys(Keys.ENTER)
from selenium.webdriver import ActionChains
action_chains = ActionChains(browser)
action_chains.key_down(Keys.CONTROL).send_keys('V').key_up(Keys.CONTROL).perform()
xpath_string = '/html/body/div[1]/div/div/div[1]/div/div[2]/div/div/div[6]/div/div/section/div/ul/li[2]/a/span'
element = browser.find_element_by_xpath(xpath_string)
action_chains.move_to_element(element).click().perform()
browser.execute_script('window.print();')

Firefox 会弹出一个打印对话框。我想知道我怎么能接受它。有没有办法绕过这个对话框直接打印,因为这不是系统对话框而是火狐的。

编辑: 根据@Prophet 的输入,我的完整更新代码

from selenium.webdriver import Firefox
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
from selenium.webdriver.support.ui import Select
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.firefox_profile import FirefoxProfile
import time
from fake_useragent import UserAgent
from selenium import webdriver
from selenium.webdriver import DesiredCapabilities
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
ua = UserAgent()
userAgent = ua.random

url = 'https://finance.yahoo.com/'
driver_path = 'geckodriver.exe'

profile = FirefoxProfile('C:\\Users\\\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\tp3cz5dm.default-release')
profile.set_preference("general.useragent.override", userAgent)

browser = Firefox(executable_path = driver_path)
browser.get(url)
profile.set_preference("browser.helperApps.neverAsk.saveToDisk", "application/pdf")
profile.set_preference("browser.helperApps.neverAsk.openFile", "application/pdf")
search_field_id = 'yfin-usr-qry'

element_search_field = browser.find_element_by_id(search_field_id)
element_search_field.clear()
element_search_field.send_keys('TSLA')
element_search_field.send_keys(Keys.ENTER)
from selenium.webdriver import ActionChains
action_chains = ActionChains(browser)
action_chains.key_down(Keys.CONTROL).send_keys('V').key_up(Keys.CONTROL).perform()
# xpath_string = '/html/body/div[1]/div/div/div[1]/div/div[2]/div/div/div[6]/div/div/section/div/ul/li[2]/a/span'
# element = browser.find_element_by_xpath(xpath_string)
# action_chains.move_to_element(element).click().perform()
browser.execute_script('window.print();')

browser.switch_to.window(browser.window_handles[-1])
time.sleep(0.5)
actionButton = browser.execute_script(
"return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-button-strip').shadowRoot.querySelector('.action-button')")
cancelButton.click()
# switch back to main window
browser.switch_to.window(driver.window_handles[0])

当我运行这个时,我得到了错误:

JavascriptException: TypeError: document.querySelector(...) is null

【问题讨论】:

    标签: python selenium selenium-webdriver printing


    【解决方案1】:

    以下两个解决方案都设计为不启动print dialog. 这些解决方案会将活动网页打印到本地打印机或 PDF 文件,而无需处理对话框.

    2021 年 8 月 19 日更新后


    我想将输出保存为 PDF,而不是打印到纸上。我很震惊使用geckodriver 和selenium 打印到PDF 是多么困难。使用“chromedriver”,您可以拨打function 'execute_cdp_cmd' and pass Page.printToPDF。 geckodriver 没有“execute_cdp_cmd”。

    当我通过Stack Overflow 寻找灵感时,我发现了多个关于使用geckodriver 和selenium 打印pdf 的未解决问题。在看到这是一个问题后,我查看了selenium 中的问题和mozilla 的错误报告。这又是其他人遇到的问题。

    一些错误报告提到打印过程中使用的某些开关不再起作用。

    profile.set_preference("print.print_to_file", True)
    profile.set_preference("print.print_to_filename", "/tmp/file.pdf")
    

    我决定查看source code for mozilla gecko-dev 寻找潜在的解决方案。经过数小时的研究,我发现上面的开关被新的开关替换了,另一个打印机变量也被替换了。经过一些测试,我能够将您的网页保存为 PDF。

    下面的代码将启用所有链接的网页打印为 PDF。我建议在代码中添加一些错误处理。我需要改进文件名部分的代码的一部分。您应该能够添加一个重命名文件的函数,这将允许您在单个会话中打印任意数量的文件。

    from time import sleep
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.options import FirefoxProfile
    
    firefox_options = Options()
    firefox_options.add_argument("--disable-infobars")
    firefox_options.add_argument("--disable-extensions")
    firefox_options.add_argument("--disable-popup-blocking")
    
    profile_options = FirefoxProfile()
    user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11.5; rv:90.0) Gecko/20100101 Firefox/90.0'
    profile_options.set_preference('profile_options = FirefoxProfile()', user_agent)
    profile_options.set_preference("print_printer", "Mozilla Save to PDF")
    profile_options.set_preference("print.always_print_silent", True)
    profile_options.set_preference("print.show_print_progress", False)
    profile_options.set_preference('print.save_as_pdf.links.enabled', True)
    profile_options.set_preference("print.printer_Mozilla_Save_to_PDF.print_to_file", True)
    
    # set your own file path
    profile_options.set_preference('print.printer_Mozilla_Save_to_PDF.print_to_filename',
                                   "tmp/testprint.pdf")
    
    
    driver = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver', options=firefox_options,
                               firefox_profile=profile_options)
    
    
    URL = 'https://finance.yahoo.com/'
    
    
    driver.get(URL)
    
    sleep(10)
    
    search_field_id = 'yfin-usr-qry'
    
    element_search_field = driver.find_element_by_id(search_field_id)
    element_search_field.clear()
    element_search_field.send_keys('TSLA')
    element_search_field.send_keys(Keys.ENTER)
    
    sleep(10)
    
    driver.execute_script("window.print()")
    
    sleep(20)
    
    driver.quit()
    

    2021 年 8 月 18 日原帖


    我决定查看您的问题,因为我对 selenium 功能感兴趣。

    我查看了geckodriver的源代码,发现printUtils.js,其中提供了打印过程中使用的开关的详细信息,例如:

    firefox_options.set_preference("print.always_print_silent", True)
    firefox_options.set_preference("print.show_print_progress", False)
    
    

    删除一些代码并添加一些代码后,我能够使用以下代码打印到我的 HP 打印机,而无需处理打印对话框:

    from time import sleep
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.options import FirefoxProfile
    
    firefox_options = Options()
    firefox_options.add_argument("--disable-infobars")
    firefox_options.add_argument("--disable-extensions")
    firefox_options.add_argument("--disable-popup-blocking")
    
    profile_options = FirefoxProfile()
    user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11.5; rv:90.0) Gecko/20100101 Firefox/90.0'
    firefox_options.set_preference('profile_options = FirefoxProfile()', user_agent)
    firefox_options.set_preference("print.always_print_silent", True)
    firefox_options.set_preference("print.show_print_progress", False)
    firefox_options.set_preference("pdfjs.disabled", True)
    
    driver = webdriver.Firefox(executable_path='/usr/local/bin/geckodriver', options=firefox_options)
    
    URL = 'https://finance.yahoo.com/'
    
    driver.get(URL)
    
    sleep(10)
    
    search_field_id = 'yfin-usr-qry'
    
    element_search_field = driver.find_element_by_id(search_field_id)
    element_search_field.clear()
    element_search_field.send_keys('TSLA')
    element_search_field.send_keys(Keys.ENTER)
    
    sleep(10)
    driver.execute_script("window.print()")
    
    ----------------------------------------
    My system information
    ----------------------------------------
    Platform:    Apple
    OS:          10.15.7
    Python:      3.9
    Selenium:    3.141
    Firefox:     90.0.2
    Geckodriver: 0.29.0
    
    ----------------------------------------
    

    【讨论】:

    • 这对我有用。这应该是一个公认的答案
    • @HammadAli 很高兴答案对您有用,并感谢您的支持。
    • 我做了这个更改'print.printer_Microsoft_Print_to_PDF.print_to_filename' 但我得到了selected printer could not be found。能否请教一下
    • @Lifeiscomplex 我在这里添加了一个问题stackoverflow.com/questions/69082942/… 你能帮我解决这个问题吗
    【解决方案2】:

    添加这些配置文件首选项应避免出现此弹出窗口:

    profile.set_preference("print.always_print_silent", True)
    profile.set_preference("print.show_print_progress", False)
    

    UPD
    涉及打印对话框后,请尝试通过此代码接受它:

    # switch to print preview window
    driver.switch_to.window(driver.window_handles[-1])
    time.sleep(0.5)
    actionButton = driver.execute_script(
    "return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('print-preview-button-strip').shadowRoot.querySelector('.action-button')")
    cancelButton.click()
    # switch back to main window
    driver.switch_to.window(driver.window_handles[0])
    

    【讨论】:

    • 感谢您的回答,但我仍然收到 Firefox 打印对话框。请指教
    • 好的,会尝试找到更多。
    • 感谢您为更新代码所做的工作。我运行了它,但现在出现了一个新错误:JavascriptException: TypeError: document.querySelector(...) is null。我已经更新了问题中的代码。
    • 我明白了.. 必须调试这个。目前没有时间做这个,如果以后有 - 会尝试这样做
    猜你喜欢
    • 2012-07-17
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多