Ce que je veux réaliser, c'est obtenir une capture d'écran d'un site Web à partir de n'importe quel site Web en python.
Env: Linux
Sur le Mac, il y a webkit2png et sur Linux + KDE, vous pouvez utiliser khtml2png . J'ai essayé le premier et cela fonctionne assez bien, et j'ai entendu parler de ce dernier étant utilisé.
J'ai récemment rencontré QtWebKit qui prétend être multiplateforme (Qt a roulé WebKit dans leur bibliothèque, je suppose). Mais je ne l'ai jamais essayé, donc je ne peux pas vous en dire plus.
Les liens QtWebKit montrent comment accéder à partir de Python. Vous devriez pouvoir utiliser au moins un sous-processus pour faire de même avec les autres.
Voici une solution simple utilisant 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')
Voici ma solution en récupérant l'aide de diverses sources. Il prend la capture d'écran de la page Web complète et la recadre (facultatif) et génère également une miniature à partir de l'image recadrée. Voici les exigences:
Exigences:
npm -g install 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 __== '__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,
)
Ce sont les images générées:
Je ne peux pas commenter la réponse d'ars, mais j'ai en fait le code de Roland Tapken fonctionnant en utilisant QtWebkit et cela fonctionne assez bien.
Je voulais juste confirmer que ce que Roland publie sur son blog fonctionne très bien sur Ubuntu. Notre version de production n'a finalement utilisé aucun de ses écrits, mais nous utilisons les liaisons PyQt/QtWebKit avec beaucoup de succès.
peut faire en utilisant du sélénium
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
Utiliser Rendertron est une option. Sous le capot, il s'agit d'un Chrome exposant les points de terminaison suivants:
/render/:url
: accédez à cet itinéraire, par exemple avec requests.get
si vous êtes intéressé par le DOM./screenshot/:url
: accédez à cet itinéraire si vous êtes intéressé par une capture d'écran.Vous installez rendertron avec npm, exécutez rendertron
dans un terminal, accédez à http://localhost:3000/screenshot/:url
et enregistrez le fichier, mais une démo est disponible sur render-tron.appspot.com permettant d'exécuter localement cet extrait Python3 sans installer le paquet npm:
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)
Vous ne mentionnez pas l'environnement dans lequel vous exécutez, ce qui fait une grande différence car il n'y a pas de navigateur Web pur Python capable de rendre HTML.
Mais si vous utilisez un Mac, j'ai utilisé webkit2png avec beaucoup de succès. Sinon, comme d'autres l'ont souligné, il existe de nombreuses options.