【问题标题】:Accessing PDF webpages by PhantomJS (Watir, GhostDriver)通过 PhantomJS (Watir, GhostDriver) 访问 PDF 网页
【发布时间】:2024-05-16 09:40:02
【问题描述】:

我正在结合使用 watir-webdriver 和 chromedriver(在 Mac OS X 上)进行可视化测试。一旦它开始工作,我就切换到使用 PhantomJS 进行无头测试。

def browser_init
  client = Selenium::WebDriver::Remote::Http::Default.new
  client.timeout = @browser_timeout 

  case @browsing_type
    when 'visual'
      @b = Watir::Browser.new :chrome, :http_client => client
    when 'headless'
      @b = Watir::Browser.new :phantomjs, :http_client => client
  end
end 

这是我的问题和问题。我测试的一些网页要么完全以 PDF 格式存储(并且 URL 以 .pdf 结尾),要么包含嵌入的 PDF 内容。这些网页在 :phantomjs 的情况下没有正确反映:它们的 @b.title@b.url 指向之前访问过的页面。在 :chrome 的情况下,pdf 页面的此信息是可访问的,因此可验证以用于测试目的。

由于 PhantomJS 以生成网页 PDF 截图的能力而闻名,我怀疑它无法在网络上打开 PDF 页面。

我是否正确理解 PhantomJS 没有 PDF 插件,还是我做错了什么?在任何一种情况下,我都将非常感谢有关 PDF 页面无头测试的任何建议。

【问题讨论】:

  • 这似乎是不可能的,我怀疑 PhantomJS 2 会改变它。虽然,我还没试过。
  • 谢谢,ArtjomB。!你知道任何其他可以工作的工具吗?无头/Xvfb 呢?我知道这个不应该在 Mac 上运行,但我可以选择切换到 Linux 平台。
  • 不,我不知道其他人。您将不得不使用 xvfb。

标签: pdf phantomjs watir-webdriver headless


【解决方案1】:

您的问题的答案实际上取决于您说“访问”时的意思。如果您的目的是渲染 PDF 并捕获图像,那么您可能超出了 phantomJS 的能力范围,需要一个真正的浏览器。 OTOH,如果您的目的是解析 PDF 并访问文档中的文本,那么您可以关注 this example 并使用一些 JS 库来处理 PDF 文件并通过 PhantomJS 运行它们

就 phantomJS 能够呈现 PDF 而言,您做了以下假设:

由于 PhantomJS 以生成 PDF 的能力而闻名 网页截图,怀疑打不开 网页上的 PDF 页面。

使用 PDF 规范将输出格式化为嵌入图像是一回事。渲染 PDF(包括图像、文本、文本效果、背景等)是另一件更困难的事情。有很多程序可以“写入”PDF 格式的内容,但不能“读取”PDF 文件。

PhantomJS 的主要目的是允许执行 Javascript 代码,而无需浏览器和页面渲染的开销。您可以使用它来执行诸如测试作为 AJAX 驱动网页的一部分的 JS 代码之类的事情。您还可以将它用作解释器来执行 JS 代码,我相信(但尚未找到确认)出于性能原因,PhantomJS 实际产生渲染网页所需的开销的唯一时间是它创建屏幕截图时。此外,由于它被设计为无头,所以有no support for plugins,这是大多数浏览器通常支持的 PDF 呈现方式。这将是阻止您实际渲染然后捕获 PDF“页面”屏幕截图的主要障碍。为此,您需要一个真正的浏览器、adobe 或其他支持 PDF 的(foxit?)插件。然后要无头运行,您需要使用 XVFB 之类的东西。

【讨论】:

  • 谢谢你,查克!您或多或少地证实了我的理解,即我正在尝试对 PhantomJS 可以和应该做的事情做一些过度的尝试。而且,是的,你引用的我的陈述忽略了写作和渲染之间明显的不对称。
  • 是的,我想做一些有限的解析。实际上,如果浏览器在不呈现页面的情况下访问该页面并知道其 URL 和标题就足够了。我至少会验证浏览器是否到达了正确的位置。您对使用 JS 库是正确的,但我还没有研究过那部分。我正在使用我的 Ruby 脚本,它盲目地将 :phantomjs (Watir 选项)用作黑匣子。 PhantomJS 只是作为二进制包安装在 OS X 或 Linux 平台上。我还不确定如何将外部 JS 代码插入到 PhantomJS 的包装中。