如何在 Selenium (Python) 中将打开的页面保存为 pdf

问题描述 投票:0回答:6

已经尝试了我在互联网上可以找到的所有解决方案,以便能够打印在Python中的Selenium中打开的页面。然而,虽然打印弹出窗口出现,但一两秒后它就会消失,并且没有保存任何 PDF。

这是正在尝试的代码。基于此处的代码 - https://stackoverflow.com/a/43752129/3973491

在 Mac 上使用 Mojave 10.14.5 进行编码。

from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.options import Options
from selenium.common.exceptions import WebDriverException
import time
import json

options = Options()
appState = {
    "recentDestinations": [
        {
            "id": "Save as PDF",
            "origin": "local"
        }
    ],
    "selectedDestinationId": "Save as PDF",
    "version": 2
}

profile = {'printing.print_preview_sticky_settings.appState': json.dumps(appState)}
# profile = {'printing.print_preview_sticky_settings.appState':json.dumps(appState),'savefile.default_directory':downloadPath}
options.add_experimental_option('prefs', profile)
options.add_argument('--kiosk-printing')
CHROMEDRIVER_PATH = '/usr/local/bin/chromedriver'

driver = webdriver.Chrome(options=options, executable_path=CHROMEDRIVER_PATH)
driver.implicitly_wait(5)
driver.get(url)
driver.execute_script('window.print();')
$chromedriver --v
ChromeDriver 75.0.3770.90 (a6dcaf7e3ec6f70a194cc25e8149475c6590e025-refs/branch-heads/3770@{#1003})

有关如何将打开的 html 页面打印为 PDF 的任何提示或解决方案。花了几个小时试图让这项工作成功。谢谢!


2019-07-11更新:

我的问题已被识别为重复,但是a)另一个问题似乎正在使用javascript代码,并且b)答案没有解决这个问题中提出的问题 - 这可能与更新的软件版本有关。使用的Chrome版本是版本75.0.3770.100(官方版本)(64位),chromedriver是ChromeDriver 75.0.3770.90。在 Mac OS Mojave 上。脚本在 Python 3.7.3 上运行。

2019-07-11更新:

将代码更改为

from selenium import webdriver
import json

chrome_options = webdriver.ChromeOptions()
settings = {
    "appState": {
        "recentDestinations": [{
            "id": "Save as PDF",
            "origin": "local",
            "account": "",
        }],
        "selectedDestinationId": "Save as PDF",
        "version": 2
    }
}
prefs = {'printing.print_preview_sticky_settings': json.dumps(settings)}
chrome_options.add_experimental_option('prefs', prefs)
chrome_options.add_argument('--kiosk-printing')
CHROMEDRIVER_PATH = '/usr/local/bin/chromedriver'
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=CHROMEDRIVER_PATH)
driver.get("https://google.com")
driver.execute_script('window.print();')
driver.quit()

现在什么也没发生。 Chrome 启动,加载 url,出现打印对话框,但似乎什么也没发生 - 默认打印机队列中没有任何内容,也没有 pdf - 我什至通过在 Mac 上查找“最近的文件”来搜索 PDF 文件。

python python-3.x selenium selenium-webdriver selenium-chromedriver
6个回答
26
投票

答案这里,当我的操作系统中没有任何其他打印机设置时有效。但是当我有另一台默认打印机时,这不起作用。

我不明白怎么做,但以这种方式做一些小改变似乎有效。

from selenium import webdriver
import json

chrome_options = webdriver.ChromeOptions()
settings = {
       "recentDestinations": [{
            "id": "Save as PDF",
            "origin": "local",
            "account": "",
        }],
        "selectedDestinationId": "Save as PDF",
        "version": 2
    }
prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(settings)}
chrome_options.add_experimental_option('prefs', prefs)
chrome_options.add_argument('--kiosk-printing')
CHROMEDRIVER_PATH = '/usr/local/bin/chromedriver'
driver = webdriver.Chrome(chrome_options=chrome_options, executable_path=CHROMEDRIVER_PATH)
driver.get("https://google.com")
driver.execute_script('window.print();')
driver.quit()

9
投票

您可以使用以下代码打印启用背景 CSS 的 A5 尺寸的 PDF:

import os
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import json
import time

chrome_options = webdriver.ChromeOptions()

settings = {
    "recentDestinations": [{
        "id": "Save as PDF",
        "origin": "local",
        "account": ""
    }],
    "selectedDestinationId": "Save as PDF",
    "version": 2,
    "isHeaderFooterEnabled": False,
    "mediaSize": {
        "height_microns": 210000,
        "name": "ISO_A5",
        "width_microns": 148000,
        "custom_display_name": "A5"
    },
    "customMargins": {},
    "marginsType": 2,
    "scaling": 175,
    "scalingType": 3,
    "scalingTypePdf": 3,
    "isCssBackgroundEnabled": True
}

mobile_emulation = { "deviceName": "Nexus 5" }
chrome_options.add_experimental_option("mobileEmulation", mobile_emulation)
chrome_options.add_argument('--enable-print-browser')
#chrome_options.add_argument('--headless')

prefs = {
    'printing.print_preview_sticky_settings.appState': json.dumps(settings),
    'savefile.default_directory': '<path>'
}
chrome_options.add_argument('--kiosk-printing')
chrome_options.add_experimental_option('prefs', prefs)

for dirpath, dirnames, filenames in os.walk('<source path>'):
    for fileName in filenames:
        print(fileName)
        driver = webdriver.Chrome("./chromedriver", options=chrome_options)
        driver.get(f'file://{os.path.join(dirpath, fileName)}')
        time.sleep(7)
        driver.execute_script('window.print();')
        driver.close()

6
投票

这是我在 Windows 上使用的解决方案:

  • 首先在此处下载 ChromeDriver :http://chromedriver.chromium.org/downloads 并安装 Selenium

  • 然后运行此代码(基于已接受的答案,稍作修改以在 Windows 上工作):

    import json
    from selenium import webdriver
    chrome_options = webdriver.ChromeOptions()
    settings = {"recentDestinations": [{"id": "Save as PDF", "origin": "local", "account": ""}], "selectedDestinationId": "Save as PDF", "version": 2}
    prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(settings)}
    chrome_options.add_experimental_option('prefs', prefs)
    chrome_options.add_argument('--kiosk-printing')
    browser = webdriver.Chrome(r"chromedriver.exe", options=chrome_options)
    browser.get("https://google.com/")
    browser.execute_script('window.print();')
    browser.close()    
    

4
投票

解决方案不是很好,但你可以截图并通过 Pillow 转换为 pdf...

from selenium import webdriver
from io import BytesIO
from PIL import Image

driver = webdriver.Chrome(executable_path='path to your driver')
driver.get('your url here')
img = Image.open(BytesIO(driver.find_element_by_tag_name('body').screenshot_as_png))
img.save('filename.pdf', "PDF", quality=100)

0
投票

您可以尝试使用这个包:https://pypi.org/project/selenium-print/

它在后台使用了selenium的

execute_cdp_cmd
功能,相当容易使用。参数可以在这里找到。

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
options = webdriver.ChromeOptions()
service = Service()
driver = webdriver.Chrome(service=service, options=options)
driver.get('http://localhost:3000')
time.sleep(2)
pdf = driver.execute_cdp_cmd("Page.printToPDF", {"printBackground": True})
pdf_data = base64.b64decode(pdf["data"])
with open("test.pdf", "wb") as f:
    f.write(pdf_data)

-6
投票

我建议下载页面源 html,可以像这样完成 在 vb.net 中: Dim Html As String = webdriver.PageSource 不知道它是如何在 python 中完成的,但我确信它非常相似 完成此操作后,您可以使用 html 解析器或使用字符串解析代码手动解析页面来选择要保存的页面部分。将要保存的部分的 html 存储在字符串中后,然后使用 html 到 pdf 转换器库或程序。对于 C# 和 vb.net 等编程语言,有很多这样的内容。我不知道 python 有什么,但我确信存在一些。只需做一些研究即可。 (有些是免费的,有些是昂贵的)

© www.soinside.com 2019 - 2024. All rights reserved.