Lo que quiero lograr es obtener una captura de pantalla del sitio web desde cualquier sitio web en python.¿Cómo puedo tomar una captura de pantalla/imagen de un sitio web usando Python?
Env: Linux
Lo que quiero lograr es obtener una captura de pantalla del sitio web desde cualquier sitio web en python.¿Cómo puedo tomar una captura de pantalla/imagen de un sitio web usando Python?
Env: Linux
En Mac, hay webkit2png y en Linux + KDE, puede usar khtml2png. Probé con el anterior y funciona bastante bien, y escuché que este último se usó.
Recientemente me encontré con QtWebKit que dice ser plataforma cruzada (Qt rodó WebKit en su biblioteca, supongo). Pero nunca lo intenté, así que no puedo contarte mucho más.
Los enlaces de QtWebKit muestran cómo acceder desde Python. Debería poder al menos usar un subproceso para hacer lo mismo con los demás.
khtml2png está desactualizado de acuerdo con el sitio web, [python-webkit2png] (https://github.com/adamn/python-webkit2png/) es recomendado por ellos. – sebix
Usted no menciona qué entorno se está ejecutando en el que hace una gran diferencia, ya que no es un navegador web de Python puro, que es capaz de renderizar HTML.
Pero si está usando una Mac, he usado webkit2png con gran éxito. De lo contrario, como han señalado otros, hay muchas opciones.
No puedo comentar la respuesta de ars, pero en realidad obtuve Roland Tapken's code ejecutándose con QtWebkit y funciona bastante bien.
Solo quería confirmar que lo que Roland publica en su blog funciona muy bien en Ubuntu. Nuestra versión de producción terminó sin usar nada de lo que escribió, pero estamos utilizando las vinculaciones PyQt/QtWebKit con mucho éxito.
Cool. Creo que esa es la lib que intentaré la próxima vez que necesite algo como esto. – ars
Terminamos poniendo un servidor RabbitMQ encima y construyendo un código para controlar los servidores Xvfb y los procesos que se ejecutan en ellos para pseudo-enhebrar las capturas de pantalla que se están construyendo. Funciona decentemente rápido con una cantidad aceptable de uso de memoria. – aezell
Aquí es una solución simple que utiliza 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')
Funciona bien, gracias. Sin embargo, funciona de manera confiable solo si se ejecuta desde la línea de comando. En un proyecto django, uno usaría subprocess.Popen() –
funciona bien desde dentro de un marco web python. Sin embargo, se necesita un poco de esfuerzo para que Webkit funcione sin cabeza. – hoju
¿Alguien experimentó problemas al usar el método de @hoju? No funciona en todas las páginas web ... – Hiatus
Aquí está mi solución por el acaparamiento de ayuda de varias fuentes. Toma una captura de pantalla completa de la página web y la cosecha (opcional) y también genera una miniatura desde la imagen recortada. Los siguientes son los requisitos:
Requisitos:
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 __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,
)
Estas son las imágenes generadas:
Funciona perfectamente en mi vista de Django. No es necesario configurar el agente de usuario predeterminado, solo la resolución de pantalla. – serfer2
¿Qué pasa si una página web requiere certificados de acceso? –
La pregunta era para Python, no NodeJS. –
probar este ..
#!/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."
Una búsqueda rápida en el sitio muestra muchos, muchos casi duplicados de esto. Este es un buen comienzo: http://stackoverflow.com/questions/713938/how-can-i-generate-a-screenshot-of-a-webpage-using-a-server-side-script – Shog9
Shog9: ¡¡¡Gracias !! su enlace tiene algunos ... lo comprobará. –
Shog9: ¿por qué no lo agrega como respuesta? por lo que puede darte puntos. –