Я багато шукав це, але не міг знайти рішення. Ось подібне запитання з можливим рішенням у Java.
Чи існує подібне рішення в Python?
Я багато шукав це, але не міг знайти рішення. Ось подібне запитання з можливим рішенням у Java.
Чи існує подібне рішення в Python?
Відповіді:
Крім селену, цей приклад також вимагає бібліотеки PIL Imaging. Іноді це ставиться як одна зі стандартних бібліотек, а іноді ні, але якщо у вас його немає, ви можете встановити його за допомогоюpip install Pillow
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
і, нарешті, результат ... логотип Stackoverflow !!!
Зараз, звичайно, це було б надмірним для простого захоплення статичного зображення, але якщо ви хочете захопити те, що вимагає Javascript, щоб дістатися до цього, це може бути життєздатним рішенням.
img = fox.get_screenshot_as_png()
а потім img = Image.open(StringIO(img))
завантажити його як зображення PIL.
BytesIO
скоріше, ніж StringIO
.
Працював у мене в python3.5
from selenium import webdriver
fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')
image = fox.find_element_by_id('hlogo').screenshot_as_png
ps
Зберегти у файл
image=driver.find_element_by_id('hlogo').screenshot(output_file_path)
image = driver.find_element_by_id('el_id').screenshot_as_png
це атрибут елемента, і як я можу зберегти це як зображення?
Я написав цю корисну функцію 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()
Він повертає зображення png відображеного елемента у вигляді байтів. Обмеження: елемент повинен поміщатися у вікні перегляду.
Для роботи з ним потрібно встановити модуль палички.
x = element.location_once_scrolled_into_view["x"] y = element.location_once_scrolled_into_view["y"]
оскільки location
може повернутися більше, ніж вікно.
Ось функція, яка робить саме це: Розміри повинні бути відлиті до цілих чисел перед передачею функції обрізання:
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')
TypeError: initial_value must be str or None, not bytes
Розширюючи коментарі у відповідь на дуже приємну відповідь RandomPhobia, ось два рішення з правильними операторами імпорту, які відкриють повноекранний знімок екрана без попереднього збереження у файл:
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()))
І оскільки я впевнений, що ваше наступне запитання: "Ну, це чудово, але який з них найшвидший?", Ось як це визначити (я вважаю, що перший метод є найшвидшим на деяку відстань):
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)
Знімок екрана за елементом:
from PIL import Image
from io import BytesIO
image = self.browser.driver.find_element_by_class_name('example.bla.bla').screenshot_as_png
im = Image.open(BytesIO(image)) # uses PIL library to open image in memory
im.save('example.png')
WebDriverException: Message: unknown error: failed to parse value of getElementRegion (Session info: chrome=78.0.3904.108)
Я перетворив відповідь @ randomphobia у функцію. Я також використав пропозицію @bummis використовувати, location_once_scrolled_into_view
а не location
для того, щоб узагальнити незалежно від розміру сторінки.
from selenium import webdriver
from PIL import Image
from io import BytesIO
def take_screenshot(element, driver, filename='screenshot.png'):
location = element.location_once_scrolled_into_view
size = element.size
png = driver.get_screenshot_as_png() # saves screenshot of entire page
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(filename) # saves new cropped image
Ось суть: https://gist.github.com/WittmannF/b714d3ceb7b6a5cd50002f11fb5a4929
img = Image.open(StringIO(base64.decodestring(driver.get_screenshot_as_base64())))