2

Python で Web ページのスクリーンショットを取得したいと考えています。このために、私はhttp://github.com/AdamN/python-webkit2png/を使用しています。

    newArgs = ["xvfb-run", "--server-args=-screen 0, 640x480x24", sys.argv[0]]
    for i in range(1, len(sys.argv)):
        if sys.argv[i] not in ["-x", "--xvfb"]:
            newArgs.append(sys.argv[i])
    logging.debug("Executing %s" % " ".join(newArgs))
    os.execvp(newArgs[0], newArgs)

基本的に、正しい引数で xvfb-run を呼び出します。しかし、次のman xvfbように述べています。

Note that the demo X clients used in the above examples will not exit on their own, so they will have to be killed before xvfb-run will exit.

つまり、このスクリプト全体がループ内にある場合 (複数のスクリーンショットを取得するため)、X サーバーが強制終了されない限り、このスクリプトは <????> を実行します。どうやってやるの?

4

1 に答える 1

5

状態のドキュメントos.execvp :

これらの関数はすべて新しいプログラムを実行し、現在のプロセスを置き換えます。彼らは戻りません。[..]

したがってos.execvp、プログラム内の他のステートメントを呼び出した後は実行されません。subprocess.Popen代わりに次を使用することもできます。

このsubprocessモジュールを使用すると、新しいプロセスを生成し、その入力/出力/エラー パイプに接続して、リターン コードを取得できます。このモジュールは、次のような他のいくつかの古いモジュールと機能を置き換えることを意図しています。

を使用すると、仮想フレームバッファ X サーバーでsubprocess.Popen実行するコードは次のようになります。xlogo

import subprocess
xvfb_args = ['xvfb-run', '--server-args=-screen 0, 640x480x24', 'xlogo']
process = subprocess.Popen(xvfb_args)

問題は、バックグラウンド プロセスでxvfb-run起動することです。Xvfb呼び出しprocess.kill()ても殺されませんXvfb(少なくとも私のマシンでは...)。私はこれを少しいじっていますが、これまでのところ、私にとってうまくいくのは次のとおりです。

import os
import signal
import subprocess

SERVER_NUM = 99  # 99 is the default used by xvfb-run; you can leave this out.

xvfb_args = ['xvfb-run', '--server-num=%d' % SERVER_NUM,
             '--server-args=-screen 0, 640x480x24', 'xlogo']
subprocess.Popen(xvfb_args)

# ... do whatever you want to do here...

pid = int(open('/tmp/.X%s-lock' % SERVER_NUM).read().strip())
os.kill(pid, signal.SIGINT)

したがって、このコードはXvfbfromのプロセス ID を読み取り、プロセス/tmp/.X99-lockに割り込みを送信します。動作しますが、ときどきエラー メッセージが表示されます (ただし、無視しても問題ないと思います)。他の誰かがよりエレガントなソリューションを提供できることを願っています。乾杯。

于 2009-11-18T11:41:38.807 に答える