使用Selenium和ChromeDriver,在打印时自动缩放页面大小

4
我正在编写一个脚本,自动在Chrome中打印一组网页。如果我要手动打印它们,我会从“比例”下拉菜单中选择“自定义”,并在下面的输入字段中输入50。

enter image description here

我无法确定在使用ChromeDriver自动批量打印这些页面时传递哪些参数来复制此设置。

appState = { "recentDestinations": [{
                "id": "Save as PDF",
                "origin": "local",
                "account": "",
                "printing.scaling": 'Custom', # <== Does it go here?
             }],
             "selectedDestinationId": "Save as PDF",
             "version": 2,
             "printing.scaling": 'Custom',  # <== Or here?
           }
profile = { 'printing.print_preview_sticky_settings.appState': json.dumps(appState),
            'printing.print_header_footer': False,

            # So many different versions of things I have tried :-(
            'printing.scaling': 'Custom',
            'printing.scaling_type': 'Custom',
            'print_preview.scaling': 'Custom',
            'print_preview.scaling_type': 'Custom',
            'printing.custom_scaling': True,
            'printing.fit_to_page_scaling': 50,
            'printing.page_scaling': True,
          }
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('prefs', profile)
br = webdriver.Chrome(options=chrome_options)

在阅读了大量Chromium源代码并试图获取提示后,上述所有不同的选项都是猜测。

https://src.chromium.org/viewvc/chrome/trunk/src/chrome/common/pref_names.cc?view=markup https://chromium.googlesource.com/chromium/src/+/master/printing/print_job_constants.cc https://chromium.googlesource.com/chromium/src/+/master/printing/print_job_constants.h

我没有线索了。接下来我该尝试什么?

3个回答

5

经过长时间的搜索和实践,我终于找到了解决方案!该设置位于appState字典中,并称为“scalingType”,但它是一个枚举类型,令人恼火的是似乎只接受数字,这些数字在这里(Github镜像)这里(googlesource)定义。3为您提供自定义缩放,然后您可以在“scaling”设置中定义(它是一个字符串!)。 所以我的设置现在如下:

chrome_options = webdriver.ChromeOptions()
appState = {"recentDestinations": [{"id": "Save as PDF", "origin": "local", "account": ""}],
            "selectedDestinationId": "Save as PDF",
            "version": 2,
            "isHeaderFooterEnabled": False,
            "isLandscapeEnabled": True,
            "scalingType": 3,
            "scaling": "141"}
prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(appState),
         'savefile.default_directory': BASE_DIR}
chrome_options.add_experimental_option('prefs', prefs)
chrome_options.add_argument('kiosk-printing')

driver = webdriver.Chrome(f'{BASE_DIR}\\chromedriver.exe', options=chrome_options)

目前可用的缩放类型选项如下:

  • 0:默认
  • 1:适合页面
  • 2:适合纸张
  • 3:自定义

但我在使用“适合”选项时并没有成功。

更一般地说,大多数这些设置/选项都可以通过查看Chromium源代码库中此文件或它所在的文件夹来确定。


谢谢!在 scalingType 后面有一个错误的方括号。这样我就不能只编辑那个了。 - jeverling
要使用“fit to”功能,您需要将标志设置为“scalingTypePdf”。 - Kim

2
我知道这不完全是你问题的答案,但可能是解决你问题的方法。
你试过不传递偏好设置,只缩小页面内容然后打印页面吗?
driver.execute_script("document.body.style.zoom='50%'")
# continue with printing

对于我来说,缩小并使用“默认”比例选项打印的效果就像将“比例”设置为50%打印页面。

这是一个很好的想法,但不幸的是对于这些特定的页面不起作用...它们有一堆由D3生成的SVG图表,并且缩放设置与它们不兼容。不过还是谢谢! - TAH

0

我最终使用了Shadow Root来改变比例。

这是我所做的。

driver1.switch_to.window(driver1.window_handles[-2])  # THIS IS THE PRINT DIALOG WINDOW - This could be -1 depending on how many windows are opened

endTime = time.time() + 10
while True:
    try:  # PRESS 'More settings' TO EXPAND
        expand = driver1.execute_script(
        "return document.querySelector('print-preview-app').shadowRoot.querySelector('print-preview-sidebar#sidebar').shadowRoot.querySelector('div#container').querySelector('print-preview-more-settings').shadowRoot.querySelector('div').querySelector('cr-expand-button')")
        if expand:
            expand.click()
            break
    except:
        pass
    time.sleep(.3)
    if time.time() > endTime:  # passed the waiting period
        driver1.switch_to.window(driver1.window_handles[0])
        break

try:  # SELECT SCALE METHOD 'CUSTOM'
    scaling = Select(driver1.execute_script(
        "return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('#container').querySelector('#moreSettings').querySelector('print-preview-scaling-settings.settings-section').shadowRoot.querySelector('print-preview-settings-section').querySelector('div').querySelector('select.md-select')"))
    scaling.select_by_value('3')
except:
    driver1.switch_to.window(driver1.window_handles[0])

try:  # ENTER SCALE NUMBER
    time.sleep(.3)
    scaling_number = driver1.execute_script(
        "return document.querySelector('print-preview-app').shadowRoot.querySelector('#sidebar').shadowRoot.querySelector('#container').querySelector('#moreSettings').querySelector('print-preview-scaling-settings').shadowRoot.querySelector('iron-collapse').querySelector('print-preview-number-settings-section').shadowRoot.querySelector('print-preview-settings-section').querySelector('#controls').querySelector('span').querySelector('#userValue').shadowRoot.querySelector('#row-container').querySelector('#input-container').querySelector('div#inner-input-container').querySelector('#input')")
    scaling_number.clear()
    scaling_number.send_keys('50')
except:
    driver1.switch_to.window(driver1.window_handles[0])

driver1.switch_to.window(driver1.window_handles[0])  # back to main window

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接