Ho cercato molto per questo ma non sono riuscito a trovare una soluzione. Ecco a similar question con una possibile soluzione in java.Come eseguire uno screenshot parziale con Selenium WebDriver in python?
Esiste una soluzione simile in Python?
Ho cercato molto per questo ma non sono riuscito a trovare una soluzione. Ecco a similar question con una possibile soluzione in java.Come eseguire uno screenshot parziale con Selenium WebDriver in python?
Esiste una soluzione simile in Python?
Questa domanda sembra essere andato a lungo senza una risposta, ma avendo appena lavorato su di esso ho pensato di passare su alcune delle cose che ho imparato
Nota: Oltre selenio questo esempio richiede anche la libreria PIL Imaging. A volte questo è messo in una delle librerie standard e, a volte non lo è, ma se non lo avete potete ottenerlo here
from selenium import webdriver
from PIL import Image
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
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()
im = Image.open('screenshot.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
e, infine, la produzione è .... rullo di tamburi la Stackoverflow logo !!!
ora, naturalmente, questo sarebbe eccessivo per solo afferrare un'immagine statica, ma se il tuo vuole afferrare qualcosa che richiede Javascript per arrivare a questo potrebbe essere una soluzione praticabile.
Questo tizio chiamato "Cherri" ha fatto un library for Selenium che include questo.
import SeleniumUrllib as selenium
selenium_urllib = selenium()
selenium_urllib.element_screenshot(selectbyid('elementid'),'path.png')
selenium_urllib.driver ## Access normal webdriver
Ho scritto questa utile funzione 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()
Restituisce l'immagine png dell'elemento visualizzato come byte. Limitazione: l'elemento deve essere inserito nella finestra.
È necessario installare il modulo bacchetta per lavorare con esso.
Bel codice! Quando provo con una lunga pagina in chrome, penso che 'x = element.location_once_scrolled_into_view [" x "] y = element.location_once_scrolled_into_view [" y "]' poiché 'location' può restituire una y più grande della finestra. – Vimos
Ecco una funzione che fa proprio questo, le dimensioni devono essere colato a interi prima di essere passato alla funzione di ritaglio:
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')
Questo è più o meno lo stesso delle risposte accettate, con l'ulteriore errore che non utilizza il selenio, come voleva l'OP. – iled
Utilizza selenio, ma l'istruzione import non è necessaria qui, Include anche la conversione di posizioni da float a int, la funzione img.crop genera un'eccezione se le posizioni non sono numeri interi – SEDaradji
Ha lavorato per me in python3.5
from selenium import webdriver
fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')
element = fox.find_element_by_id('hlogo')
image = driver.find_element_by_id(html_id_image_captcha).screenshot_as_png
Funziona perfettamente su Firefox (testato usando 56.0.1), ma non su Chrome (60.0.3112.78). –
Espansione sui commenti in risposta alla risposta molto bella di RandomPhobia, ecco due soluzioni con istruzioni di importazione corrette che apriranno uno screenshot a schermo intero senza prima salvare in un file:
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()))
E perché sono sicuro che la prossima domanda è: "Beh questo è grande, ma che uno è più veloce?", Ecco come determinare esso (ho trovato il primo metodo per essere il più veloce da una certa distanza):
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)
Puoi anche ottenere lo screenshot direttamente nella memoria: 'img = Image.open (StringIO (base64.decodestring (driver.get_screenshot_as_base64())))' – ejk314
Confermo che questa soluzione (insieme al suggerimento di @ ejk314) funziona molto bene con Selenium 2.38.4, utilizzando il driver di Firefox – cjauvin
Ottima risposta, grazie mille! –