【问题标题】:Phantomjs can't open filenamePhantomjs 无法打开文件名
【发布时间】:2014-02-12 11:50:08
【问题描述】:

我正在用 phantomjs 编写一些咖啡脚本来截取多个 url。不过,每次我尝试运行它时,都会收到一条错误消息,Can't open <filename>。是什么赋予了?这是我的代码:

  page = require('webpage').create()

  page.viewportSize =
    width: 1024
    height: 760

  urls = phantom.args
  i = 1
  for url in urls
    do (url) ->
      output = "screenshot-#{i}.png"
      page.open url, (status) ->
        if status isnt 'success'
          console.log "Error opening url \"#{page.reason_url}\": #{page.reason}"
          phantom.exit(1)
        else
          console.log "Page opened.."
          window.setTimeout (->
            page.clipRect =
              top: 0
              left: 0
              width: 1024
              height: 760
            page.render(output)
          ), 200
      i += 1

  phantom.exit()

我尝试注释掉,似乎失败的部分是 page.open(url)。奇怪的是错误消息说文件本身无法打开。

【问题讨论】:

  • 您是否尝试将“google.com”附加为第一个网址?也许错误消息是有效的。
  • 是的,我尝试直接输入一个字符串,但它似乎没有工作:(
  • 尝试硬编码?喜欢urls = ['http://google.com']
  • 这似乎也不起作用。我已经用一个简单的page.open 'http://www.google.com', (status)-> console.log "--->#{status}" 将它简化到最低限度,但我得到了同样的错误Can't open 'test.js.coffee' 我开始认为 phantomjs 的 open 方法有什么问题。
  • 我认为这归结为这段代码不起作用:page.open('http://github.com/', (status)-> console.log("Status: #{status}") page.render('github.png') )

标签: coffeescript screenshot phantomjs


【解决方案1】:

(顺便说一句:我认为第 14 行有一个剪切和粘贴错误。我相信你想要 #{url} 代替 #{page.reason_url}。)

我在这里看到两个问题,或者一个问题以多种方式表现出来。

page.open 方法是异步的——这就是它接受回调函数(你的 (status)->... 的东西)的原因。

这会导致您的代码出现两种类型的问题:

  1. 您在第 28 行的 phantom.exit() 调用超出了 for 循环(从第 9 行开始)和回调方法(从第 12 行开始)的范围。

    因为open调用是异步的,当urls['http://google.com']时,for循环会调用page.open('http://google.com/')然后跳转到phantom.exit(),在页面加载完成或者回调被调用之前。

    您需要推迟您的phantom.exit() 调用,直到page.render(output) 方法完成。在 page.render(output) 之后移动 phantom.exit() -- 并同时缩进 -- page.render(output) 将使您的程序适用于单个 URL。

  2. 即使在回调中使用phantom.exit,当将多个 URL 传递给您的程序时,您仍然会遇到问题。同样,因为page.open 是异步的,您实际上是在快速连续多次调用page.open(然后在所有这些页面加载之前退出)。

    此外,与常规的单一网络浏览器选项卡一样,Phantom 的page 对象不能真正一次打开多个页面。

要修复您的程序,需要确保 (a) 一个 URL 已加载并且 rendered 在继续下一个之前,以及 (b) 在所有 URL 都已加载之前不要调用 phantom.exit()已渲染。

有几种方法可以解决这个问题(谷歌为“nodejs 异步 for 循环”或类似的东西),但根据您的需要,每次调用程序只呈现一个页面可能更容易。

这是您的程序的一个版本,针对 PhantomJS 2 进行了更新,并设置为只呈现一个 URL:

system = require('system')
page = require('webpage').create()

page.viewportSize =
  width: 1024
  height: 760

url = system.args[2]
output = "screenshot-#{Date.now()}.png"
page.open url, (status) ->
  if status isnt 'success'
    console.error "Error opening url \"#{url}\": #{page.reason}"
    phantom.exit(1)
  else
    console.log "Page opened..."
    window.setTimeout (->
      page.clipRect =
        top: 0
        left: 0
        width: 1024
        height: 760
      page.render(output)
      console.log "Page rendered..."
      phantom.exit()
    ), 200

由于 Phantom 不再直接解析 CoffeeScript,要运行它,您需要先“编译”成 JavaScript,如下所示:

coffee -c foo.coffee
phantomjs foo.js "http://www.google.com/"

这对我来说似乎工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    相关资源
    最近更新 更多