Prendre une capture d'écran de la page entière avec le Sélénium Python avec chromedriver
Après avoir essayé différentes approches... je suis tombé sur cette page pour prendre fullpage capture d'écran avec chromedriver, le sélénium et le python.
code original ici: http://seleniumpythonqa.blogspot.com/2015/08/generate-full-page-screenshot-in-chrome.html (et je copie le code dans cette annonce ci-dessous)
Il utilise PIL et il fonctionne très bien!!!!! Cependant il y a une question... qui est elle capte fixe les en-têtes et les répétitions pour l'ensemble de la page et aussi manque certaines parties de la page lors de changement de page. exemple d'url pour prendre une capture d'écran:
http://www.w3schools.com/js/default.asp
Comment éviter la répétition des en-têtes avec ce code... Ou est-il la meilleure option qui utilise python... ( je ne sais pas java et ne souhaitez pas utiliser java).
Veuillez voir la capture d'écran du résultat courant et de l'exemple de code ci-dessous.
test.py
"""
This script uses a simplified version of the one here:
https://snipt.net/restrada/python-selenium-workaround-for-full-page-screenshot-using-chromedriver-2x/
It contains the *crucial* correction added in the comments by Jason Coutu.
"""
import sys
from selenium import webdriver
import unittest
import util
class Test(unittest.TestCase):
""" Demonstration: Get Chrome to generate fullscreen screenshot """
def setUp(self):
self.driver = webdriver.Chrome()
def tearDown(self):
self.driver.quit()
def test_fullpage_screenshot(self):
''' Generate document-height screenshot '''
#url = "http://effbot.org/imagingbook/introduction.htm"
url = "http://www.w3schools.com/js/default.asp"
self.driver.get(url)
util.fullpage_screenshot(self.driver, "test.png")
if __name__ == "__main__":
unittest.main(argv=[sys.argv[0]])
util.py
import os
import time
from PIL import Image
def fullpage_screenshot(driver, file):
print("Starting chrome full page screenshot workaround ...")
total_width = driver.execute_script("return document.body.offsetWidth")
total_height = driver.execute_script("return document.body.parentNode.scrollHeight")
viewport_width = driver.execute_script("return document.body.clientWidth")
viewport_height = driver.execute_script("return window.innerHeight")
print("Total: ({0}, {1}), Viewport: ({2},{3})".format(total_width, total_height,viewport_width,viewport_height))
rectangles = []
i = 0
while i < total_height:
ii = 0
top_height = i + viewport_height
if top_height > total_height:
top_height = total_height
while ii < total_width:
top_width = ii + viewport_width
if top_width > total_width:
top_width = total_width
print("Appending rectangle ({0},{1},{2},{3})".format(ii, i, top_width, top_height))
rectangles.append((ii, i, top_width,top_height))
ii = ii + viewport_width
i = i + viewport_height
stitched_image = Image.new('RGB', (total_width, total_height))
previous = None
part = 0
for rectangle in rectangles:
if not previous is None:
driver.execute_script("window.scrollTo({0}, {1})".format(rectangle[0], rectangle[1]))
print("Scrolled To ({0},{1})".format(rectangle[0], rectangle[1]))
time.sleep(0.2)
file_name = "part_{0}.png".format(part)
print("Capturing {0} ...".format(file_name))
driver.get_screenshot_as_file(file_name)
screenshot = Image.open(file_name)
if rectangle[1] + viewport_height > total_height:
offset = (rectangle[0], total_height - viewport_height)
else:
offset = (rectangle[0], rectangle[1])
print("Adding to stitched image with offset ({0}, {1})".format(offset[0],offset[1]))
stitched_image.paste(screenshot, offset)
del screenshot
os.remove(file_name)
part = part + 1
previous = rectangle
stitched_image.save(file)
print("Finishing chrome full page screenshot workaround...")
return True
OriginalL'auteur ihightower | 2017-01-18
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire en modifiant le CSS de l'en-tête avant de la capture d'écran:
MODIFIER: Mettre cette ligne après votre fenêtre de défilement:
Dans votre util.py, ce sera:
Si le site est à l'aide de la
header
balise, vous pouvez le faire avecfind_element_by_tag_name("header")
Vous ne pouvez pas savoir à l'avance comment chaque site web mis en place leur en-tête. Mais vous pouvez faire une supposition. Je vais ajouter un exemple.
votre code a fonctionné, mais avec quelques petites glitch.. qu'est-il inclus l'en-tête sur certaines pages. Donc, après l'ajout de sommeil 0,2 secondes.. cela a fonctionné parfaitement. j'ai mis à jour le code et a également marqué votre réponse. L'espoir de faire la modification dans votre réponse est correcte pour stackoverflow.
OriginalL'auteur Moshisho
Cela fonctionne pour moi. Il enregistre l'intégralité de la page de capture d'écran.
Pour plus d'informations, vous pouvez lire les docs de l'api:
http://selenium-python.readthedocs.io/api.html
OriginalL'auteur Javed Karim
Après avoir pris connaissance de l'approche de @Moshisho.
Mon plein fonctionnant de manière autonome script est... (ajouté le sommeil 0.2 après chaque rouleau et la position)
OriginalL'auteur ihightower
Cette réponse augmente en avant des réponses par am05mhz et Javed Karim.
Il suppose headless mode, et qu'une fenêtre de la taille d'option n'a pas été prévue initialement. Avant d'appeler cette fonction, la page est chargée entièrement ou suffisamment.
Il tente de définir la largeur et la hauteur à la fois à ce qui est nécessaire. La capture d'écran de la page entière peut parfois inclure une inutile barre de défilement verticale. Une façon d'éviter en général la barre de défilement est de prendre une capture d'écran de l'élément de corps de la place. Après l'enregistrement d'une capture d'écran, il revient à la taille de ce qu'il était à l'origine, à défaut de quoi la taille pour la prochaine capture d'écran peuvent ne pas s'installer correctement.
Finalement, cette technique peut ne pas fonctionner très bien pour quelques exemples.
Si à l'aide de Python âgés de plus de 3.6, supprimer les annotations de type à partir de la définition de la fonction.
required_height + 74
fonctionne pour moi pour l'instant.OriginalL'auteur A-B-B
Ne sais pas si les gens sont toujours à avoir ce problème.
J'ai fait un petit hack qui fonctionne assez bien et qui joue bien avec les zones dynamiques. Espérons que cela aide
OriginalL'auteur jeremie s
J'ai changé le code pour Python 3.6, il sera peut-être utile pour quelqu'un:
OriginalL'auteur A.Minachev
Pourquoi ne pas simplement obtenir la largeur et la hauteur de la page, puis redimensionnez le pilote? Ce sera quelque chose comme ceci
Cela va faire une capture d'écran de votre page entière sans la nécessité de fusionner ensemble les différents morceaux.
OriginalL'auteur Vali
Captures d'écran sont limitées à la fenêtre d'affichage, mais vous pouvez contourner ce problème en s'emparant de l'
body
élément, comme le webdriver permettra de saisir l'ensemble de l'élément, même si elle est plus grande que la fenêtre d'affichage. Cela vous évitera d'avoir à traiter avec le défilement et la couture des images, cependant, vous pourriez voir des problèmes avec le pied de position (comme dans la capture d'écran ci-dessous).Testé sur Windows 8 avec Chrome Pilote.
Retourne: (taille complète: https://i.stack.imgur.com/ppDiI.png)
OriginalL'auteur alexalex
Il y avait une erreur dans le code suggéré plus tôt, dans la ligne 2. Voici le corrigé. Étant un noob ici, pas en mesure de modifier mon propre post.
Parfois la baove n'obtient pas de meilleurs résultats. Alors pouvez utiliser une autre méthode pour obtenir la hauteur de tous les éléments et de la somme à régler la capture de la hauteur comme ci-dessous:
BTW, il fonctionne sur FF.
OriginalL'auteur Javed Karim
Modifier légèrement @ihightower et @A. Minachev du code, et de le faire fonctionner sous mac retina:
OriginalL'auteur Charlie Chen
J'ai modifié jeremie s' répondre, afin de ne récupérer l'url une fois.
default_width
ou ce qu'il a été ou auraient dû l'être. J'ai maintenant un plus récente réponse qui corrige ce problème.OriginalL'auteur am05mhz
Vous pouvez utiliser Splinter
Splinter est une couche d'abstraction sur navigateur existant outils d'automatisation tels que le Sélénium
Il est une nouvelle fonctionnalité
browser.screenshot(..., full=True)
dans la nouvelle version0.10.0
.full=True
option fera le plein de capture d'écran pour vous.OriginalL'auteur Sergei