Take entire page screenshot with selenium python

Viewed 5037

I am trying to take a full-page screenshot using selenium and chromedriver, but I am getting this half screenshot. I have tried other methods but so far only this one works and it takes only the half-page screenshot.

Anyone can fix this using another trick, also do attach the output result.

Page Screenshot

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options


options = webdriver.ChromeOptions()
options.headless = True
driver = webdriver.Chrome(options=options)

URL = "http://stevens.ekkel.ai"

driver.get(URL)

S = lambda X: driver.execute_script('return document.body.parentNode.scroll'+X)
driver.set_window_size(S('Width'),S('Height')) # May need manual adjustment                                                                                                                
driver.find_element_by_tag_name('body').screenshot('web_screenshot.png')

driver.quit()
4 Answers

I am using a PyPI package: Selenium-Screenshot
You can install it by using the command - pip install Selenium-Screenshot
Details of this package can be found here: https://pypi.org/project/Selenium-Screenshot/

Sharing a sample patch on how to use this package for full page screenshot:

from Screenshot import Screenshot_Clipping
        
#Saving screenshot
ob=Screenshot_Clipping.Screenshot()
img=ob.full_Screenshot(driver,save_path=r'D:/OneDrive -Libin/Python/Sel_python/Pytest/Screenshots',image_name="Screenshot1.png")
    
driver.close()
driver.quit()

Check the screenshot for your reference: https://i.stack.imgur.com/opgPi.png

I managed to get the whole page, without iterations, keys or page downs or the lambda function using code from here and only changing the screen size dimensions.

Trouble is, for your webpage at least, the width has to be re-adjusted (expanded) to take the picture of the entire header, and even then it doesn't take the full width and ends up looking stitched together.

The header width is problem in simple selenium-only code. (on my system):

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options() 
chrome_options.add_argument('--headless')
chrome_options.add_argument("--window-size=3200x20800") # ANYTHING MORE THAN 3200 width my pycharm cant cope (Rendering error)

driver = webdriver.Chrome(options=chrome_options, executable_path=r"C:\Users\User\Documents\chromedriver_win32\chromedriver.exe") # webdriver.Chrome(options=options)
outFileName = (r'D:\08102020 Random Work\NewFolder4PythonOut')
driver.maximize_window()

URL = "http://stevens.ekkel.ai"

driver.get(URL) #time.sleep(0.5)
#driver.maximize_window()

driver.get_screenshot_as_file(outFileName+"/"+"capture4.png")

Also, That --window-size=3200x20800") size I the most I could make it on my machine (limited ram space left) before Pycharm wouldn't run or inform me in error message of rendering problems. But even if I could run entire page maximum, the screen shot would look like this , so I recommend you use @Libin Thomas pytest code.

My chrome (deliberately downgraded to chrome 89 as webdriver for chrome 90 doesn't exist yet or I could find), also in a very highly markedup authoritative SO thread (here, here or elsewhere - I've read so much but haven't found a simple generic solution for us) and I [mistake it? or take it? that], as one of the highly marked answers in SO says, Chrome Webdriver doesn't have a "take whole webpage screenshot" function yet, as you can see in the picture, but FireFox does (which I don't want to use, cant and have deleted. RAM)

enter image description here

EDIT 18:20 pm

After doing all that , and a bit more, it dawned on me that I was looking at it the wrong way. ZOOM is what I needed.

I did manage to get a screen shot of the whole thing, clearly, in one go, using driver.execute_script("document.body.style.zoom='10%'") after driver opens the page.

(its helped me understand why even your first attempt, and my successful page down scrolling one, our headers appeared stretched and where narrower than the rest of the body).

The true header is huge compared to the rest, but atleast the screen shot is real and not stretched, or only the middle section of it, Its the whole thing with the real as-is header.

(although probably not what you wanted).

IMAGE Screenshot in saved folder

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options() #
chrome_options.add_argument('--headless')
chrome_options.headless = True

#https://stackoverflow.com/questions/56201707/how-to-take-screenshot-of-youtube-page-without-opening-the-browser-in-python-or
#chrome_options.add_argument("--window-size=4000x5800")

driver = webdriver.Chrome(options=chrome_options, executable_path=r"C:\Users\User\Documents\chromedriver_win32\chromedriver.exe") # webdriver.Chrome(options=options)
#driver.maximize_window()

outFileName = (r'D:\08102020 Random Work\NewFolder4PythonOut')


URL = "http://stevens.ekkel.ai"

driver.get(URL) #time.sleep(0.5)
#driver.maximize_window()
driver.execute_script("document.body.style.zoom='10%'")
driver.get_screenshot_as_file(outFileName+"/"+"capture5.png")

I hope I've helped in some small way, even if not the way you maybe wanted.

Kasif,

Im not the best, but I seem to be able to get it done, in one screenshot, no header problems, no repeating header, all headless browsing, and without any extra module imports.

I've approached it with pagedowns/ scrolling to get the full screenshot.

May need cleaning up the code a little bit, but its working as you want.

try:

import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys


options = webdriver.ChromeOptions()
options.headless = True
driver = webdriver.Chrome(options=options)

URL = "http://stevens.ekkel.ai"

driver.get(URL)

S = lambda X: driver.execute_script('return document.body.parentNode.scroll'+X)

browser = webdriver.Chrome(executable_path=r"C:\Users\User\Documents\chromedriver_win32\chromedriver.exe", options=options)
elem = browser.find_element_by_tag_name("body")

# make page downs =>10 to catch the whole page

no_of_pagedowns = 15

while no_of_pagedowns:

    elem.send_keys(Keys.PAGE_DOWN)
    time.sleep(0.2)

    driver.set_window_size(S('Width'), S('Height'))  # May need manual adjustment
    driver.find_element_by_tag_name('body').screenshot('web_screenshot4.png')
    no_of_pagedowns -= 1

driver.quit()

As mentioned in the comment, the below patch will remove the navigation ribbon and will take full page screenshot. Also I have made few edits to save the .png file as the urlname.

import pytest
from Screenshot import Screenshot_Clipping
from selenium import webdriver
import time
    
###add class and mothods accordingly
page_url="http://stevens.ekkel.ai/"
driver.get(page_url)
time.sleep(5)

js_string = "var element = document.getElementsByClassName(\'w3-row w3-padding w3-black\');element[0].parentNode.removeChild(element[0]);"
driver.execute_script(js_string)
time.sleep(2)

# Saving screenshot
correction=page_url.replace("/","")
ss_name=correction.replace(":","")

ob=Screenshot_Clipping.Screenshot()
img_url=ob.full_Screenshot(
driver,save_path=r'D:/OneDrive - Libin/Python/Sel_python/Pytest/Screenshots',image_name="{}.png".format(ss_name))
 
Related