在python脚本中截取vnc会话的屏幕截图

时间:2012-06-13 17:13:56

标签: python screenshot vnc

我需要能够在OSX下的python脚本中截取(vnc会话,如果把它放在标题中并且标签不够清晰)。远程系统已经运行了我用于其他目的的vnc服务器,并且最终将涵盖所有常见的桌面操作系统,因此我宁愿继续使用vnc而不是其他解决方案。

我的测试服务器上没有打开vnc窗口,因为它运行无头。我已经尝试过使用vncdotool,但是我宁愿不用shell,并且试图模仿控制流会导致问题,因为Twisted不允许你重启反应堆,但是如果你让它运行就会阻塞主线程,似乎在尝试在单独的线程或进程中运行反应器时出现问题...

有没有人有任何想法?

5 个答案:

答案 0 :(得分:1)

阅读完评论后,您真正想要做的就是拍摄运行Flash游戏的远程网络浏览器的屏幕截图。

...您正在使用selenium来测试这些远程Web浏览器。

...你为什么不让selenium为你截取屏幕截图?

http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/TakesScreenshot.html

答案 1 :(得分:1)

以tangentStorm建议为基础,使用selenium截取屏幕截图。试试这个。打开src/Selenium2Library/keywords/_screenshot.py并查看第24-30行。

     background leaking when the page layout is somehow broken.
     """
     path, link = self._get_screenshot_paths(filename)
     self._current_browser().save_screenshot(path)

     # Image is shown on its own row and thus prev row is closed on purpose
     self._html('</td></tr><tr><td colspan="3"><a href="%s">'

删除行self._current_browser().save_screenshot(path)并直接添加到其位置

if hasattr(self._current_browser(), 'get_screenshot_as_file'):
    self._current_browser().get_screenshot_as_file(path)
else:
    self._current_browser().save_screenshot(path)

所以它应该看起来像:

    background leaking when the page layout is somehow broken.
    """
    path, link = self._get_screenshot_paths(filename)
if hasattr(self._current_browser(), 'get_screenshot_as_file'):
    self._current_browser().get_screenshot_as_file(path)
else:
    self._current_browser().save_screenshot(path)
    # Image is shown on its own row and thus prev row is closed on purpose
    self._html('</td></tr><tr><td colspan="3"><a href="%s">'

然后尝试使用selenium来截取屏幕截图。

参考:Fix

答案 2 :(得分:0)

我不知道任何在Python for OSX中执行此操作的库。

但是,至少还有其他三种获取屏幕截图的方法:

  1. 使用jython中的java.awt.Robot类。 (除了扭曲可能不会在jython上运行。)
  2. 将Apple的ScreenSnapshot示例移至Cython并将其编译为python模块。 (当然你可以在C中做同样的事情,但Cython让它变得更有趣。)
  3. 如果您可以将服务器移动到win32,或者只是通过parallels在Mac上运行win32,那么您可以使用python映像库的ImageGrab模块。
  4. 但是,我认为炮击操作系统仍然是最简单的答案。而不是试图让它在一个进程中运行,只需要运行两个进程:主要的扭曲进程,以及使用线程或其他任何东西的其他服务器。

    然后,当您想截取屏幕截图时,只需来回传递消息。您可以使用简单的套接字连接(只需在您的扭曲服务器中编写另一个处理程序,并将屏幕截图服务器作为客户端连接)来执行此操作... ...

    如果是我,我可能会使用像RabbitMQ这样的AMQP服务器来处理消息传递,但这对你正在做的事情来说可能是过度的。

答案 3 :(得分:0)

根据您的代码,您可以使用deferToThread来运行对screencapture的调用并返回文件路径或pil.Image实例(或您需要的任何内容)。

使用http://twistedmatrix.com/documents/current/core/howto/gendefer.html#auto5处的示例,它可能看起来像......

from subprocess import call
import tempfile
from twisted.internet import reactor, threads
import Image ## pip install pil


## Blocking code that takes the screenshot and saves to file
def take_screenshot():
    tmp_file_path = tempfile.mktemp(suffix='.png')
    # os.system('screencapture %s' % tmp_file_path)
    retcode = call(['screencapture', tmp_file_path])
    if retcode < 0:
        img = Image.open(tmp_file_path)
        return img
    else:
        return None


## Callback fired by the deferToThread
def do_something_with_screenshot(img):
    print img.filename, img.format, img.size, img.mode
    reactor.stop() ## just here for this example


def run():
    # get our Deferred which will be called with the largeFibonnaciNumber result
    d = threads.deferToThread(take_screenshot)
    # add our callback to print it out
    d.addCallback(do_something_with_screenshot)


if __name__ == '__main__':
    run()
    reactor.run()

答案 4 :(得分:0)

也许您可以说服机器人框架或Selenium向Eggplant Drive发送CaptureScreen Sensetalk命令。

TestPlant论坛中的Taking a Screenshot帖子提到了这个命令。