[PYTHON] Patch pour prendre des captures d'écran en taille réelle dans Chrome

Ceci est l'article du 5ème jour du Calendrier de l'Avent Selenium / Appium 2014. La veille était «Gestion de la configuration environnementale pour exécuter Selenium» par hiroshitoda-prospire.

Bonjour. Je m'appelle myhr et je suis ingénieur de test. Aujourd'hui, je voudrais vous présenter un correctif pour prendre des captures d'écran en taille réelle dans Chrome. Je pense que cela a déjà été introduit dans d'autres articles, mais cette fois je voudrais l'expliquer en détail pour les débutants.

Contexte

Pour le contexte, voir l'article de l'an dernier par hiroshitoda-prospire "Conseils pour prendre des captures d'écran avec Selenium WebDriver. J'ai été autorisé à faire référence.

J'ai également pris des captures d'écran avec Firefox et Chrome.

--Pour les pages verticalement longues

スクリーンショット 2014-12-04 16.14.35.png

--Pour les pages longues horizontalement

スクリーンショット 2014-12-04 16.16.14.png

Firefox est capable de capturer la fin de la page, mais Chrome n'affiche que ce que vous pouvez voir sur l'écran du navigateur. Par conséquent, contrairement à Firefox, vous pouvez voir que chaque fois que vous prenez une capture d'écran, vous prenez la peine de mettre le navigateur que vous utilisez au premier plan.

RemoteWebDriver Modes The remote webdriver comes in two flavours:

  • Client mode: where the language bindings connect to the remote instance. This is the way that the FirefoxDriver, OperaDriver and the RemoteWebDriver client normally work.
  • Server mode: where the language bindings are responsible for setting up the server, which the driver running in the browser can connect to. The ChromeDriver works in this way.

Je pense que la raison pour laquelle le comportement est différent uniquement pour Chrome Driver est probablement liée à ce domaine, mais j'apprécierais que vous m'en disiez plus.

Environnement d'exploitation

env version
Python 3.4.2
Pillow ※ 2.4.0
selenium 2.44.0
ChromeDriver 2.9.248307
Chrome 39.0.2171.71 (64-bit)

manière

La méthode est simple. Je vais le faire de manière forcée et boueuse.

Paramètres variables

var description var description
view_width ※ Taille horizontale du navigateur stitched_image Image qui devient une capture d'écran
view_height ※ Taille verticale du navigateur tmp_image Image faisant partie de la capture d'écran
total_width ※ Taille horizontale de la page row_count Nombre de rouleaux verticaux
total_height ※ Taille verticale de la page col_count Nombre de parchemins sur le côté
scroll_width Mètre de taille horizontale à défilement new_width La taille horizontale restante de la page
scroll_height Mètre de taille verticale à défilement new_height La taille verticale restante de la page

※ Valeur fixe

  1. Supposons que la taille de la page entière soit grande à la fois verticalement et horizontalement, comme indiqué ci-dessous.
    Capture d'écran 2014-12-05 6.01.47.png
    À ce moment, initialisez à scroll_width, scroll_height, row_count, col_count = 0.

  2. Prenez une capture d'écran jusqu'à ce qu'elle atteigne le bord droit de la page et répétez le défilement de la largeur de l'écran.
    Capture d'écran 2014-12-05 15.48.55.png
    Augmentez col_count chaque fois que vous faites défiler horizontalement.
    Bien que ce ne soit pas obligatoire, si le nom de fichier de tmp_image est tmp_ {row_count} _ {col_count} .png, il sera plus facile à comprendre lorsque vous regarderez le fichier plus tard.
    Collez tmp_image dans stitched_image aux positions scroll_width et scroll_height.

  3. Lorsque la taille de défilement dépasse la taille restante de la page, découpez la quantité restante, enregistrez-la dans tmp_image et collez-la dans stitched_image.
    Capture d'écran 2014-12-05 16.08.23.png
    Puis faites défiler verticalement de la hauteur de l'écran et ramenez le défilement horizontal vers la gauche.
    scroll_height + = view_height; row_count ++; scroll_width, col_count = 0

  4. Répétez le processus ci-dessus jusqu'à ce que vous atteigniez le coin inférieur droit de la page. (Couper et coller de la même manière que le défilement horizontal lors du défilement vertical MAX)
    Enfin, enregistrez stitched_image dans le nom de fichier spécifié (passé en argument) et renvoyez True.

code

https://gist.github.com/yui3880/a63ced61806d8517c4a3

from PIL import Image
import time

def save_screenshot(self, filename, fullsize=False):
	filepath = '/'.join(filename.split('/')[:-1])
	if fullsize:
		#Faites défiler vers le haut à gauche de la page
		self.execute_script("window.scrollTo(0, 0);")

		#Obtenir la taille de la page
		total_height = self.execute_script("return document.body.scrollHeight")
		total_width = self.execute_script("return document.body.scrollWidth")

		#Obtenir la taille de l'écran
		view_width = self.execute_script("return window.innerWidth")
		view_height = self.execute_script("return window.innerHeight")
		
		#Pour le traitement d'image
		stitched_image = Image.new("RGB", (total_width, total_height))

		#Pour l'opération de défilement
		scroll_width = 0
		scroll_height = 0

		row_count = 0
		#Traitement de défilement vertical §
		while scroll_height < total_height:
			#Initialisation du défilement horizontal
			col_count = 0
			scroll_width = 0
			self.execute_script("window.scrollTo(%d, %d)" % (scroll_width, scroll_height)) 
			#Traitement de défilement horizontal
			while scroll_width < total_width:
				if col_count > 0:
					#Défilement horizontal pour la taille de l'écran
					self.execute_script("window.scrollBy("+str(view_width)+",0)") 
					
				tmpname = filepath + '/tmp_%d_%d.png' % (row_count, col_count)
				self.get_screenshot_as_file(tmpname)
				time.sleep(3)

				#Lorsque vous atteignez le bord droit ou inférieur, coupez l'image et cousez_Coller à l'image
				if scroll_width + view_width >= total_width or scroll_height + view_height >= total_height:
					new_width = view_width
					new_height= view_height
					if scroll_width + view_width >= total_width:
						new_width = total_width - scroll_width
					if scroll_height + view_height >= total_height:
						new_height = total_height - scroll_height
					tmp_image = Image.open(tmpname)
					tmp_image.crop((view_width - new_width, view_height - new_height, view_width, view_height)).save(tmpname)
					stitched_image.paste(Image.open(tmpname), (scroll_width, scroll_height))
					scroll_width += new_width

				#Coller normalement
				else:
					stitched_image.paste(Image.open(tmpname), (scroll_width, scroll_height))
					scroll_width += view_width
					col_count += 1

			scroll_height += view_height
			time.sleep(3)

		
		#Assemblé au nom de fichier spécifié_stockage d'images
		stitched_image.save(filename)
		return True

	# fullsize=Si faux, prenez une capture d'écran normale
	else:
		self.get_screenshot_as_file(filename)

Où frappez-vous

Si vous n'utilisez pas de wrapper

Appliquons-le directement à la liaison de langue.

--Pour python: {$ PYTHONPATH} / site-packages / webdriver / chrome / webdriver.py

  ...
  from selenium.common.exceptions import WebDriverException
  from .service import Service
  from .options import Options
+ from PIL import Image
+ import time

  class WebDriver(RemoteWebDriver):
  ...
+     def save_screenshot(self, filename, fullsize=False):
+         #Obtenir la taille de la page
+         total_width = self.execute_script("return document.body.scrollWidth")
+         total_height = self.execute_script("return document.body.scrollHeight")
  ...

--Avantage: si vous le mettez, toutes les captures d'écran de Chrome seront prises de cette manière, et la méthode d'appel est la même qu'avant

Si vous utilisez un wrapper ou une bibliothèque interne

Veuillez vous changer en pilote Web ou quelque chose dans la méthode de votre capture d'écran.

Touche tactile

Vient ensuite nkns165. Je vous remercie.

Recommended Posts

Patch pour prendre des captures d'écran en taille réelle dans Chrome
Captures d'écran de la pêche sur le Web avec du sélénium et Chrome.
Selenium-Screenshot est utile pour les captures d'écran de pages Web dans Python3, Selenium et Google Chrome