Была у меня аналогичная задача. Стандартное .find_element_by_xpath(location).screenshot_as_png работало хорошо в firefox, в chrome не работало, если не ошибаюсь. Тогда в интернете нашел вариант ниже. Он снимает скриншот видимой области, прокручивает страницу, делает еще скриншот, и так далее. Потом все это склеивает в один скриншот. Данное решение работает в firefox, chrome, safari. Проблема возникнет, если на сайте есть закрепленные элементы, на склеенном скриншоте они будут повторяться (пример: закрепленная шапка сайта в мобильной версии)
.
from io import BytesIO
from selenium import webdriver
from PIL import Image, ImageChops, ImageDraw
def full_screenshot(browser: webdriver, offset: int = 0) -> Image:
""" Получение полного скриншота содержимого окна браузера
offset - начальное смещение"""
img_list = [] # для хранения фрагментов изображения
# Определение размера окна браузера
height = browser.execute_script("""return Math.max(
document.documentElement.clientHeight,
window.innerHeight
);""")
# Определение высоты содержимого окна браузера
max_window_height = browser.execute_script("""return Math.max(
document.body.scrollHeight,
document.body.offsetHeight,
document.documentElement.clientHeight,
document.documentElement.scrollHeight,
document.documentElement.offsetHeight
);""")
# Скроллим страницу и добавляем скриншот видимого окна браузера в img_list
while offset < max_window_height:
browser.execute_script(f"window.scrollTo(0, {offset});")
img = Image.open(BytesIO((browser.get_screenshot_as_png())))
img_list.append(img)
offset += height
# Обрезание последнего изображения
box = (0, height - height * (max_window_height / height - max_window_height // height), img_list[-1].size[0],
img_list[-1].size[1])
img_list[-1] = img_list[-1].crop(box)
# Определение размеров нового изображения, создание холста
img_frame_height = sum([img_frag.size[1] for img_frag in img_list])
img_frame = Image.new('RGB', (img_list[0].size[0], img_frame_height))
# Объединение изображений в одно
offset = 0
for img_fragment in img_list:
img_frame.paste(img_fragment, (0, offset))
offset += img_fragment.size[1]
return img_frame