I am using python and selenium in writing a program to automate a report creation. This program has to be portable and scalable — others will need to be able to use it on their own laptops or desktop monitors. As a result, I need to be able to capture and crop screenshots of a specific object on a page. Specifically, it screenshots three rows (grouped together), where the height of the three rows is the height of the tag that I find, and the width of it is the width of the tag that I find.
Here is what I have tried:
#fullscreen window
driver.fullscreen_window()
#find correct set of rows containing user input date
tgtElement = driver.find_element(By.XPATH, ("//a[contains(text(), '" + userDate + "')]"))
#get the y value
location = tgtElement.location
size = tgtElement.size
yVal = location.get("y")
#scroll to correct row
driver.execute_script("window.scrollTo(0, " + str(yVal - 150) + ");")
#get size of screen as reference, specifically height
window_handle = FindWindow(None, "myWindow")
window_rect = GetWindowRect(window_handle)
windowHeight = window_rect[3]
#take screenshot of the whole screen
driver.save_screenshot(pngLocation)
im = Image.open(pngLocation)
# -2 to get the second to last instance of the row span.
# obtains the proper element
boxElement = driver.find_elements(By.CSS_SELECTOR, "td[rowspan = '3']")[-2].rect
# get dimensions of the three rows combined
rowHeight = boxElement.get("height")
rowXPos = boxElement.get("x")
rowYPos = boxElement.get("y")
boxElement = driver.find_element(By.CSS_SELECTOR, "tr").rect
#get the width of the full row
rowWidth = boxElement.get("width")
#get dimensions of the whole webpage
bodyElement = driver.find_element(By.CSS_SELECTOR, "html[lang='en']").rect
bodyHeight = bodyElement.get("height")
bodyWidth = bodyElement.get("width")
#return the ratio to find where the edges of the box are relative to the the window
relativeRight = float(rowXPos+rowWidth) / float(bodyWidth)
relativeLeft = float(rowXPos) / float(bodyWidth)
#attempts to account for the fact that the length of the webpage may be less than the length of the weekend
if bodyHeight < windowHeight:
relativeTop = float((windowHeight -rowYPos)) / float(windowHeight)
relativeBottom = float((windowHeight -rowYPos) + rowHeight) / float(windowHeight)
else:
relativeTop = float((windowHeight - (bodyHeight-rowYPos))) / float(windowHeight)
relativeBottom = float((windowHeight - (bodyHeight-rowYPos)) + rowHeight) / float(windowHeight)
print(str(bodyElement))
width, height = im.size
print(str(im.size))
# left = (width - distFromRight) - 75
# right = (width - distFromRight) + 1100
# top = (height - distFromBottom) - 50
# bottom = (height - distFromBottom) + 200
# calculate the ratio for all of the edges
left = relativeLeft*width
right = relativeRight*width
top = relativeTop*height
bottom = relativeBottom*height
# left = width / 5
# top = height - (height / 3)
# right = 4 * width /5
# bottom = height
# crop the image
im1 = im.crop((left, top-(height/5), right, bottom))
im1.save(pngLocation)
My objective here was to scroll to the target location, (found by using a user input date). Then, finding the location and size of the box (3 rows) I am trying to capture. Then, finding where it is located relative to the window size. Then, after the screenshot, cropping the screenshot using ratios for each of the edges of the box compared to the edge of the window that was screenshotted.
This works for my laptop (probably because I designed and tested it on there), but even in that case, I was running into an issue where the length of the html was not longer than the window. Thus, I added the
if bodyHeight < windowHeight:
relativeTop = float((windowHeight -rowYPos)) / float(windowHeight)
relativeBottom = float((windowHeight -rowYPos) + rowHeight) / float(windowHeight)
else:
relativeTop = float((windowHeight - (bodyHeight-rowYPos))) / float(windowHeight)
relativeBottom = float((windowHeight - (bodyHeight-rowYPos)) + rowHeight) / float(windowHeight)
However, this still didn’t fix that issue either. I am able to reliably find the object and identify its edges every time, but the screenshot still varies by monitor.
Overall, I am wondering if I am wasting my time trying to do this contextual screenshot, and if it is even possible given different website layouts for different screens.
Jack Williams is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.