【问题标题】:Python + Selenium + PhantomJS render to PDFPython + Selenium + PhantomJS 渲染为 PDF
【发布时间】:2023-04-03 00:15:01
【问题描述】:

当 PhantomJS 与 Selenium 和 Python 结合使用时,是否可以使用 PhantomJS's 渲染到 PDF 功能? (即通过 Selenium 在 Python 中模仿 page.render('file.pdf') 行为)。

我意识到这使用了GhostDriver,而GhostDriver 在打印方式上并没有真正支持太多。

如果不是 Selenium 的其他替代方案是可能的,我会全力以赴。

【问题讨论】:

  • @Amit:相当广泛,因为我一直在使用它。甚至 Phaseit 自己也说过“PyPDF2 不了解 HTML”。它不会可靠地呈现任何 HTML。
  • @Rejected 您是否需要屏幕截图在测试期间以准确的状态出现?或者您只是想加载页面并呈现为 PDF?

标签: python selenium phantomjs


【解决方案1】:

你可以使用selenium.selenium.capture_screenshot('file.png'),但这会给你一个png而不是pdf的屏幕截图。似乎没有办法将屏幕截图作为 pdf 格式获取。

这里是 capture_screenshot 的文档:http://selenium.googlecode.com/git/docs/api/py/selenium/selenium.selenium.html?highlight=screenshot#selenium.selenium.selenium.capture_screenshot

【讨论】:

  • PDF 是一个关键因素。由于多种原因,例如文本搜索、表单、嵌入式媒体等,我无法下拉到简单的图像。
【解决方案2】:

试过pdfkit?它可以从 html 页面呈现 PDF 文件。

【讨论】:

  • 我也调查过。 PDFKit 转换 HTML -> PDF,但没有其他功能。遗憾的是,无法进行内容分析以确定页面在 PDF 之前是否包含所需的内容。
  • 是的,我在使用 PDFKit 时遇到了同样的问题,我想要更高级的渲染,将它与 JS 框架一起使用非常麻烦.. :(
  • “内容分析以确定页面是否包含所需的内容”-> 那么,您不能自己进行内容分析,如果匹配,那么您只需将其发送到使用 pdfkit 呈现。我就是这样做的。
  • @Jonathan:然后我不渲染同一个页面,我使用 PDFKit 渲染它的第二次检索,它重新获取并重新渲染。如果我转到 PageA 并且它动态生成内容,再次返回它意味着可以更改内容。如果我只是保存 HTML 在本地打开它进行转换,我会面临很多潜在问题(相对链接、热链接保护等)
  • pdfkit 可以从字符串渲染.. @Rejected
【解决方案3】:

@rejected,我知道你提到不想使用子进程,但是...

您实际上可能比您预期的更多地利用子流程通信。从理论上讲,您可以采用 Ariya's stdin/stdout example 并将其扩展为相对通用的包装脚本。它可能首先接受要加载的页面,然后在该页面上侦听(并执行)您的测试操作。最终,您可以启动.render,甚至可以进行通用捕获以进行错误处理:

try {
  // load page & execute stdin commands
} catch (e) {
  page.render(page + '-error-state.pdf');
}

【讨论】:

  • 执行通过标准输入接收的代码需要通过eval 完成,根据我尝试这样做的经验,它既不安全也不可靠。除非我弄错了?
  • 虽然您希望对您的输入保持谨慎(从可靠性的角度来看),但您可能不必担心安全性,因为(我假设)您拥有该流程。
  • 您还可以将特定命令等列入白名单,以便更快地抛出意外错误。但是,我设想的最佳方案是您将屏幕捕获之前可能发生的测试(或其他逻辑)提取到单独的 .js 文件中,并将其加载到页面中(phantomjs.org/api/phantom/method/inject-js.html)。您最多可以让 Python 传递一个 arg 以供特定文件 JS 加载。
【解决方案4】:

这是一个使用 selenium 和 GhostDriver 特殊命令的解决方案 (它应该从 GhostDriver 1.1.0 和 PhantomJS 1.9.6 开始工作,用 PhantomJS 1.9.8 测试):

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Download a webpage as a PDF."""


from selenium import webdriver


def download(driver, target_path):
    """Download the currently displayed page to target_path."""
    def execute(script, args):
        driver.execute('executePhantomScript',
                       {'script': script, 'args': args})

    # hack while the python interface lags
    driver.command_executor._commands['executePhantomScript'] = ('POST', '/session/$sessionId/phantom/execute')
    # set page format
    # inside the execution script, webpage is "this"
    page_format = 'this.paperSize = {format: "A4", orientation: "portrait" };'
    execute(page_format, [])

    # render current page
    render = '''this.render("{}")'''.format(target_path)
    execute(render, [])


if __name__ == '__main__':
    driver = webdriver.PhantomJS('phantomjs')
    driver.get('http://stackoverflow.com')
    download(driver, "save_me.pdf")

另请参阅我对同一问题的回答 here。

【讨论】:

  • 有没有办法用 Chromedriver 和 Selenium 做到这一点?谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-02-16
  • 2016-11-21
  • 2014-01-31
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-17
相关资源
最近更新 更多