J'ai beaucoup cherché cela, mais je n'ai pas trouvé de solution. Voici ne question similaire avec une solution possible en Java.
Existe-t-il une solution similaire en Python?
Cette question semble être restée longtemps sans réponse, mais après y avoir travaillé, j'ai pensé que je transmettrais certaines des choses que j'ai apprises
Remarque: Outre Selenium, cet exemple nécessite également la bibliothèque d'imagerie PIL. Parfois, cela est mis dans l'une des bibliothèques standard et parfois ce n'est pas le cas, mais si vous ne l'avez pas, vous pouvez l'obtenir ici
from Selenium import webdriver
from PIL import Image
from io import BytesIO
fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')
# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
png = fox.get_screenshot_as_png() # saves screenshot of entire page
fox.quit()
im = Image.open(BytesIO(png)) # uses PIL library to open image in memory
left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']
im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image
et la sortie finale est .... roulement de tambour le logo Stackoverflow !!!
maintenant, bien sûr, ce serait exagéré de simplement saisir une image statique, mais si vous voulez saisir quelque chose qui nécessite Javascript pour y arriver, cela pourrait être une solution viable.
A travaillé pour moi en python3.5
from Selenium import webdriver
fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')
image = fox.find_element_by_id('hlogo').screenshot_as_png
J'ai écrit cette fonction utile de python3.
from base64 import b64decode
from wand.image import Image
from Selenium.webdriver.remote.webelement import WebElement
from Selenium.webdriver.common.action_chains import ActionChains
import math
def get_element_screenshot(element: WebElement) -> bytes:
driver = element._parent
ActionChains(driver).move_to_element(element).perform() # focus
src_base64 = driver.get_screenshot_as_base64()
scr_png = b64decode(src_base64)
scr_img = Image(blob=scr_png)
x = element.location["x"]
y = element.location["y"]
w = element.size["width"]
h = element.size["height"]
scr_img.crop(
left=math.floor(x),
top=math.floor(y),
width=math.ceil(w),
height=math.ceil(h),
)
return scr_img.make_blob()
Il renvoie l'image png de l'élément affiché sous forme d'octets. Limitation: l'élément doit tenir dans la fenêtre.
Vous devez installer le module de baguette pour pouvoir l'utiliser.
Voici une fonction qui fait exactement cela, les tailles doivent être converties en entiers avant d'être passées à la fonction de recadrage:
from PIL import Image
from StringIO import StringIO
def capture_element(element,driver):
location = element.location
size = element.size
img = driver.get_screenshot_as_png()
img = Image.open(StringIO(img))
left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']
img = img.crop((int(left), int(top), int(right), int(bottom)))
img.save('screenshot.png')
En développant les commentaires en réponse à la très belle réponse de RandomPhobia, voici deux solutions avec des déclarations d'importation correctes qui ouvriront une capture d'écran en plein écran sans d'abord enregistrer dans un fichier:
from Selenium import webdriver
from PIL import Image
from StringIO import StringIO
import base64
DRIVER = 'chromedriver'
browser = webdriver.Chrome(DRIVER)
browser.get( "http:\\\\www.bbc.co.uk" )
img 1 = Image.open(StringIO(base64.decodestring(browser.get_screenshot_as_base64())))
img 2 = Image.open(StringIO(browser.get_screenshot_as_png()))
Et parce que je suis sûr que votre prochaine question est: "Eh bien, c'est bien mais laquelle est la plus rapide?", Voici comment la déterminer (je trouve que la première méthode est la plus rapide d'une certaine distance):
import timeit
setup = '''
from Selenium import webdriver
from PIL import Image
from StringIO import StringIO
import base64
DRIVER = 'chromedriver'
browser = webdriver.Chrome(DRIVER)
browser.get( "http:\\\\www.bbc.co.uk" )
file_name = 'tmp.png'
'''
print timeit.Timer('Image.open(StringIO(browser.get_screenshot_as_png()))', setup=setup).repeat(2, 10)
print timeit.Timer('Image.open(StringIO(base64.decodestring(browser.get_screenshot_as_base64())))', setup=setup).repeat(2, 10)
print timeit.Timer('browser.get_screenshot_as_file(file_name); pil_img = Image.open(file_name)', setup=setup).repeat(2, 10)
Ce gars nommé "Cherri" a fait un bibliothèque pour Selenium qui inclut cela.
import SeleniumUrllib as Selenium
selenium_urllib = Selenium()
Selenium_urllib.element_screenshot(selectbyid('elementid'),'path.png')
Selenium_urllib.driver ## Access normal webdriver