2009-07-28 3 views
39

Что я хочу достичь, так это получить снимок экрана на любом веб-сайте в python.Как я могу сделать снимок экрана/изображение веб-сайта с помощью Python?

Env: Linux

+4

Быстрый поиск по сайту вызывает много, много близких к нему дубликатов. Вот хороший старт: http://stackoverflow.com/questions/713938/how-can-i-generate-a-screenshot-of-a-webpage-using-a-server-side-script – Shog9

+0

Shog9: Спасибо! у вашей ссылки есть некоторые ... проверит. –

+0

Shog9: почему бы вам не добавить его в качестве ответа? поэтому он может дать вам очки. –

ответ

8

На Mac есть webkit2png и на Linux + KDE вы можете использовать khtml2png. Я пробовал первое, и он работает очень хорошо, и слышал о том, что последний используется.

Я недавно наткнулся на QtWebKit, который претендует на кросс-платформу (Qt закатил WebKit в свою библиотеку, я думаю). Но я никогда не пробовал, поэтому больше не могу рассказать.

Ссылки QtWebKit показывают, как получить доступ с Python. Вы должны иметь возможность по крайней мере использовать подпроцесс, чтобы сделать то же самое с другими.

+0

khtml2png устарел в соответствии с веб-сайтом, [python-webkit2png] (https://github.com/adamn/python-webkit2png/) рекомендуется ими. – sebix

0

Вы не говоря уже о какой среде вы работаете в, что делает большой разницы, потому что это не чисто Python веб-браузер, который способен рендеринга HTML.

Но если вы используете Mac, я с большим успехом использовал webkit2png. Если нет, как указывали другие, есть много вариантов.

5

Я не могу комментировать ответ ars, но я действительно получил Roland Tapken's code, работающий с использованием QtWebkit, и он работает очень хорошо.

Просто хотел подтвердить, что то, что пишет Roland в своем блоге, отлично работает на Ubuntu. Наша производственная версия не использовала ничего из того, что он написал, но мы с большим успехом используем привязки PyQt/QtWebKit.

+0

Прохладный. Я думаю, что это lib, я попробую в следующий раз мне нужно что-то вроде этого. – ars

+0

Мы закончили тем, что разместили на нем сервер RabbitMQ и создали некоторый код для управления серверами Xvfb и запущенными в них процессами для псевдополяции создаваемых скриншотов. Он работает достаточно быстро с приемлемым объемом использования памяти. – aezell

38

Вот простое решение с использованием WebKit: http://webscraping.com/blog/Webpage-screenshots-with-webkit/

import sys 
import time 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
from PyQt4.QtWebKit import * 

class Screenshot(QWebView): 
    def __init__(self): 
     self.app = QApplication(sys.argv) 
     QWebView.__init__(self) 
     self._loaded = False 
     self.loadFinished.connect(self._loadFinished) 

    def capture(self, url, output_file): 
     self.load(QUrl(url)) 
     self.wait_load() 
     # set to webpage size 
     frame = self.page().mainFrame() 
     self.page().setViewportSize(frame.contentsSize()) 
     # render image 
     image = QImage(self.page().viewportSize(), QImage.Format_ARGB32) 
     painter = QPainter(image) 
     frame.render(painter) 
     painter.end() 
     print 'saving', output_file 
     image.save(output_file) 

    def wait_load(self, delay=0): 
     # process app events until page loaded 
     while not self._loaded: 
      self.app.processEvents() 
      time.sleep(delay) 
     self._loaded = False 

    def _loadFinished(self, result): 
     self._loaded = True 

s = Screenshot() 
s.capture('http://webscraping.com', 'website.png') 
s.capture('http://webscraping.com/blog', 'blog.png') 
+0

Хорошо работает, спасибо. Однако работает надежно только при запуске из командной строки. В проекте django можно использовать subprocess.Popen() –

+1

отлично работает в рамках веб-фрейма python. Однако предпринимает определенные усилия, чтобы заставить webkit работать без головы. – hoju

+2

У кого-нибудь возникли проблемы с использованием метода @hoju? Он не работает на каждой веб-странице ... – Hiatus

33

Вот мое решение, захватывая помощь из различных источников. Он требует полного захвата экрана веб-страницы, и он обрабатывает его (необязательно) и генерирует эскиз с обрезанного изображения. Ниже приведены требования:

Требования:

  1. Установка NodeJS
  2. Использование менеджера пакетов в Node установить phantomjs: npm -g install phantomjs
  3. Установите селен (в вашем virtualenv, если вы используете это)
  4. Установить imageMagick
  5. Добавить phantomjs к системному пути (по окнам)

import os 
from subprocess import Popen, PIPE 
from selenium import webdriver 

abspath = lambda *p: os.path.abspath(os.path.join(*p)) 
ROOT = abspath(os.path.dirname(__file__)) 


def execute_command(command): 
    result = Popen(command, shell=True, stdout=PIPE).stdout.read() 
    if len(result) > 0 and not result.isspace(): 
     raise Exception(result) 


def do_screen_capturing(url, screen_path, width, height): 
    print "Capturing screen.." 
    driver = webdriver.PhantomJS() 
    # it save service log file in same directory 
    # if you want to have log file stored else where 
    # initialize the webdriver.PhantomJS() as 
    # driver = webdriver.PhantomJS(service_log_path='/var/log/phantomjs/ghostdriver.log') 
    driver.set_script_timeout(30) 
    if width and height: 
     driver.set_window_size(width, height) 
    driver.get(url) 
    driver.save_screenshot(screen_path) 


def do_crop(params): 
    print "Croping captured image.." 
    command = [ 
     'convert', 
     params['screen_path'], 
     '-crop', '%sx%s+0+0' % (params['width'], params['height']), 
     params['crop_path'] 
    ] 
    execute_command(' '.join(command)) 


def do_thumbnail(params): 
    print "Generating thumbnail from croped captured image.." 
    command = [ 
     'convert', 
     params['crop_path'], 
     '-filter', 'Lanczos', 
     '-thumbnail', '%sx%s' % (params['width'], params['height']), 
     params['thumbnail_path'] 
    ] 
    execute_command(' '.join(command)) 


def get_screen_shot(**kwargs): 
    url = kwargs['url'] 
    width = int(kwargs.get('width', 1024)) # screen width to capture 
    height = int(kwargs.get('height', 768)) # screen height to capture 
    filename = kwargs.get('filename', 'screen.png') # file name e.g. screen.png 
    path = kwargs.get('path', ROOT) # directory path to store screen 

    crop = kwargs.get('crop', False) # crop the captured screen 
    crop_width = int(kwargs.get('crop_width', width)) # the width of crop screen 
    crop_height = int(kwargs.get('crop_height', height)) # the height of crop screen 
    crop_replace = kwargs.get('crop_replace', False) # does crop image replace original screen capture? 

    thumbnail = kwargs.get('thumbnail', False) # generate thumbnail from screen, requires crop=True 
    thumbnail_width = int(kwargs.get('thumbnail_width', width)) # the width of thumbnail 
    thumbnail_height = int(kwargs.get('thumbnail_height', height)) # the height of thumbnail 
    thumbnail_replace = kwargs.get('thumbnail_replace', False) # does thumbnail image replace crop image? 

    screen_path = abspath(path, filename) 
    crop_path = thumbnail_path = screen_path 

    if thumbnail and not crop: 
     raise Exception, 'Thumnail generation requires crop image, set crop=True' 

    do_screen_capturing(url, screen_path, width, height) 

    if crop: 
     if not crop_replace: 
      crop_path = abspath(path, 'crop_'+filename) 
     params = { 
      'width': crop_width, 'height': crop_height, 
      'crop_path': crop_path, 'screen_path': screen_path} 
     do_crop(params) 

     if thumbnail: 
      if not thumbnail_replace: 
       thumbnail_path = abspath(path, 'thumbnail_'+filename) 
      params = { 
       'width': thumbnail_width, 'height': thumbnail_height, 
       'thumbnail_path': thumbnail_path, 'crop_path': crop_path} 
      do_thumbnail(params) 
    return screen_path, crop_path, thumbnail_path 


if __name__ == '__main__': 
    ''' 
     Requirements: 
     Install NodeJS 
     Using Node's package manager install phantomjs: npm -g install phantomjs 
     install selenium (in your virtualenv, if you are using that) 
     install imageMagick 
     add phantomjs to system path (on windows) 
    ''' 

    url = 'http://stackoverflow.com/questions/1197172/how-can-i-take-a-screenshot-image-of-a-website-using-python' 
    screen_path, crop_path, thumbnail_path = get_screen_shot(
     url=url, filename='sof.png', 
     crop=True, crop_replace=False, 
     thumbnail=True, thumbnail_replace=False, 
     thumbnail_width=200, thumbnail_height=150, 
    ) 

Это сгенерированные изображения:

+0

Прекрасно работает в моем представлении Django. Нет необходимости устанавливать пользовательский агент по умолчанию, только разрешение экрана. – serfer2

+0

Что делать, если на веб-странице требуются сертификаты для доступа? –

+2

Вопрос был для Python, а не NodeJS. –

-1

Попробуйте это ..

#!/usr/bin/env python 

import gtk.gdk 

import time 

import random 

while 1 : 
    # generate a random time between 120 and 300 sec 
    random_time = random.randrange(120,300) 

    # wait between 120 and 300 seconds (or between 2 and 5 minutes) 
    print "Next picture in: %.2f minutes" % (float(random_time)/60) 

    time.sleep(random_time) 

    w = gtk.gdk.get_default_root_window() 
    sz = w.get_size() 

    print "The size of the window is %d x %d" % sz 

    pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,sz[0],sz[1]) 
    pb = pb.get_from_drawable(w,w.get_colormap(),0,0,0,0,sz[0],sz[1]) 

    ts = time.time() 
    filename = "screenshot" 
    filename += str(ts) 
    filename += ".png" 

    if (pb != None): 
     pb.save(filename,"png") 
     print "Screenshot saved to "+filename 
    else: 
     print "Unable to get the screenshot." 

 Смежные вопросы

  • Нет связанных вопросов^_^