Python을 사용하여 웹 사이트의 스크린 샷/이미지를 어떻게 찍을 수 있습니까?

StackOverflow https://stackoverflow.com/questions/1197172

문제

내가 달성하고 싶은 것은 Python의 모든 웹 사이트에서 웹 사이트 스크린 샷을 얻는 것입니다.

Env : Linux

도움이 되었습니까?

해결책

Mac에는 있습니다 webkit2png 그리고 Linux+KDE에서는 사용할 수 있습니다 Khtml2png. 나는 전자를 시도했고 그것은 아주 잘 작동하며 후자가 사용하는 것을 들었습니다.

나는 최근에왔다 Qtwebkit 이것은 크로스 플랫폼이라고 주장합니다 (QT는 webkit을 라이브러리로 굴 렸습니다). 그러나 나는 그것을 시도한 적이 없으므로 훨씬 더 말할 수 없습니다.

Qtwebkit 링크는 Python에서 액세스하는 방법을 보여줍니다. 최소한 하위 프로세스를 사용하여 다른 사람들과 똑같이 할 수 있어야합니다.

다른 팁

다음은 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')

다음은 다양한 출처의 도움을 받아 내 솔루션입니다. 전체 웹 페이지 화면 캡처가 필요하고 자르기 (선택 사항)를 자르고 자른 이미지에서도 썸네일을 생성합니다. 다음은 요구 사항입니다.

요구 사항 :

  1. nodejs를 설치하십시오
  2. Node의 패키지 관리자 사용 Phantomjs 설치 : npm -g install phantomjs
  3. Selenium 설치 (사용중인 경우 VirtualEnV에서)
  4. Imagemagick을 설치하십시오
  5. 시스템 경로에 Phantomjs 추가 (Windows)

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,
    )

이것들은 생성 된 이미지입니다.

Ars의 답변에 대해서는 언급 할 수 없지만 실제로는 Roland Tapken의 코드 Qtwebkit을 사용하여 실행하면 잘 작동합니다.

Roland가 자신의 블로그에 게시 한 내용이 Ubuntu에서 훌륭하게 작동하는지 확인하고 싶었습니다. 우리의 생산 버전은 그가 쓴 내용을 사용하지 않았지만 PYQT/QTWebkit 바인딩을 많이 사용하여 많은 성공을 거두고 있습니다.

셀레늄을 사용하여 할 수 있습니다

from selenium import webdriver

DRIVER = 'chromedriver'
driver = webdriver.Chrome(DRIVER)
driver.get('https://www.spotify.com')
screenshot = driver.save_screenshot('my_screenshot.png')
driver.quit()

https://sites.google.com/a/chromium.org/chromedriver/getting-started

사용 렌더 트론 옵션입니다. 후드 아래에서 이것은 다음 엔드 포인트를 노출시키는 헤드리스 크롬입니다.

  • /render/:url:이 경로에 액세스하십시오 requests.get DOM에 관심이 있다면.
  • /screenshot/:url: 스크린 샷에 관심이있는 경우이 경로에 액세스하십시오.

NPM을 사용하여 RenderTron을 설치합니다 rendertron 한 터미널에서 액세스 http://localhost:3000/screenshot/:url 파일을 저장하지만 데모를 사용할 수 있습니다. render-tron.appspot.com NPM 패키지를 설치하지 않고이 Python3 스 니펫을 로컬로 실행할 수 있습니다.

import requests

BASE = 'https://render-tron.appspot.com/screenshot/'
url = 'https://google.com'
path = 'target.jpg'
response = requests.get(BASE + url, stream=True)
# save file, see https://stackoverflow.com/a/13137873/7665691
if response.status_code == 200:
    with open(path, 'wb') as file:
        for chunk in response:
            file.write(chunk)

당신은 당신이 실행중인 환경을 언급하지 않으므로 HTML을 렌더링 할 수있는 순수한 파이썬 웹 브라우저가 없기 때문에 큰 차이를 만듭니다.

하지만 Mac을 사용하는 경우 사용했습니다 webkit2png 큰 성공으로. 그렇지 않다면 다른 사람들이 지적했듯이 많은 옵션이 있습니다.

이 시도..

#!/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."
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top