0

Webページのスクリーンショットを作成し、画像のようにユーザーに返すことができるオンラインサービスを構築しています。使い方:

1)Xサーバー用の仮想フレームバッファーを作成します-さらに実際のウィンドウを作成しないでください

2)環境変数にどの表示を使用するかをメモします

3)子プロセスを作成します(そうでない場合、前のポイントは有効になりません)

4)子プロセスでwebkit.WebView()を作成し、ウィンドウを「表示」してWebページをロードします

5)ページが完全にロードされたという通知を受け取ったら-スクリーンショットを作成してファイルに保存します(これはプロジェクトのこのステップにのみあります-ユーザーのブラウザに戻す方法もありますか?私は知っていますContent type: image/pngが、さらに-gtk。 gdk.Pixbuf.save(stdout_file_name)?)

それで!問題!コンソールから実行するとpython parent.cgi(すべてが完璧ですが、Webブラウザーで開くparent.cgi(サーバーが実行される)と、実際のブラウザーページで無限にロードしようとします。サーバー上のプロセスでは、プラス3が表示されます(明らかに正しい)プロセス:apache2Xvfbpython

python return_picture.cgi
python /home/argon/www/wool/cgi-bin/parent.cgi
bash/sh -c python return_picture.cgi

コード:

parent.cgi:

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

import gtk,webkit,gobject,sys,os,time,subprocess,logging
import cgitb,cgi
import signal
cgitb.enable()

logging.basicConfig(format = u'%(levelname)-8s [%(asctime)s] %(message)s', level = logging.INFO, filename = u'mylog.log')
logging.critical('ONE MORE TIME')
print "Content-Type: text/html;charset=utf-8"
print '' #it is importantly required

class writer(object):
    def write(self, data):
        logging.critical(data)

sys.stdout = writer()
sys.stderr = writer()
class XServer():
    def __init__(self, silence_xvfb=True, display='1', screen='0', xvfb_timeout=3):
        self.pidfile = '/tmp/.X%s-lock' % display
        redirect = '> /dev/null 2>&1'
        redirect = ''
        if not silence_xvfb:
            redirect = ''
        cmd = ' '.join(['Xvfb', ':'+display, '-screen', screen, '1600x1200x24', redirect])
        if(os.path.isfile(self.pidfile)):
            self._kill_xvfb()
        #os.system(cmd+' &')
        subprocess.Popen(cmd+' &', shell=True) #works througth filenodes thats why it is impossible to redirect to log - overriding of file.write() does not make sense
        print 'XVFB STARTED'
        self.xvfb = True
        start = time.time()
        while(True):
            diff = time.time() - start
            if(diff > xvfb_timeout):
                raise SystemError("Timed-Out waiting for Xvfb to start - {0} sec".format(xvfb_timeout))
            if(os.path.isfile(self.pidfile)):
                break
            else:
                time.sleep(0.05)

        os.putenv('DISPLAY', ':%s' % display)

    def _kill_xvfb(self):
        pid = int(open(self.pidfile).read().strip())
        os.kill(pid, signal.SIGINT)
        print 'KILLED'

    def __del__(self):
        # Kill the frame buffer
        if(self.xvfb):
            self._kill_xvfb()

xserver = XServer()

logging.debug('lets create child')
child = subprocess.Popen("python return_picture.cgi",shell=True,stdout=subprocess.PIPE)
s=child.stdout.readline()
print 'there again'

return_picture.cgi:

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

from blessings import Terminal
import gtk,webkit,gobject,sys,os,time,signal,logging
import cgitb,cgi

cgitb.enable()
t = Terminal()
logging.basicConfig(format = u'%(levelname)-8s [%(asctime)s] %(message)s', level = logging.DEBUG, filename = u'mylog.log')

class writer(object):
    def write(self, data):
        logging.critical(data)

sys.stdout = writer()
sys.stderr = writer()
logging.debug('IN CHILD')
#print "Content-Type: image/png"
#print "Content-Type: text/html;charset=utf-8"
#print '' #it is importantly required
#print 'hello'
web=webkit.WebView()
win=gtk.Window()
index = 0
finished = False
def finished_cb(web_view,sig,res):
    global finished
    global index
    index += 1
    #print index,': ',
    status = web_view.get_property("load-status").value_name
    logging.debug(str(index)+': '+status)
    if "FINISH" in status and not finished:
        finished = True
        gobject.timeout_add(500,drawWindow)
        print 'timeout'
        return

sig2= "resource-load-finished"
web.connect(sig2, finished_cb)
url = 'http://google.com/'
web.open(url)

win.add(web)

def drawWindow():
    width, height = win.get_size()
    pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height)

    screenshot = pixbuf.get_from_drawable(win.window, win.get_colormap(), 
                                          0, 0, 0, 0, width, height)
    ret = screenshot.subpixbuf(0,0,300,20)
    ret = screenshot
    stdot_filename = os.readlink('/proc/self/fd/0') 
    print stdot_filename
    #screenshot.save(stdot_filename, 'png')

    gtk.main_quit()
    screenshot.save('screenshot.png', 'png')
    print 'screenshot saved'
win.show_all()
gtk.main()
4

1 に答える 1

1

スクリーンショットのリクエストをそれらの生成から切り離す必要があります。

スクリーンショットを撮るためのURLをWebページに挿入してキューに入れます。このキューからアイテムを引き出し、スクリーンショット生成スクリプトを実行するプロセスを用意します。

このようにして、Webブラウザーはスクリーンショットプロセスの実行を待たず(とにかく失敗する可能性があります)、重複する要求を簡単に処理でき、同時に実行できるよりも多くのWebKitインスタンスを起動するサーバーを圧倒することはありません。 。

それが私がhttp://bookmarkly.comでそれをする方法です

于 2012-08-24T21:24:34.610 に答える