0

I'd like to take a screenshot of a Tableau Public visualisation by taking a screenshot of the entire website and cropping it. I'm able to find height and width of my element, but my x and y coordinates are wrong. I assume x = 0 and y = 0 are the coordinates of my element within the iframe, but not the ones within the website.

How do I get the coordinates for the iframe so I can crop my image corectly? At the moment it just crops the left part of the website.

from selenium import webdriver
import time
from PIL import Image

driver = webdriver.Chrome(executable_path=r'C:\Program Files\chromedriver.exe')

# Maximise window and zoom out
driver.get('chrome://settings/')
driver.maximize_window()
driver.execute_script('chrome.settingsPrivate.setDefaultZoom(0.6);')

driver.get("https://public.tableau.com/en-gb/gallery/super-pac-origins?tab=viz-of-the-day&type=viz-of-the-day")

time.sleep(5)
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))

element = driver.find_element_by_xpath('//div[@id = "tab-dashboard-region"]')

location = element.location
print(location)
size = element.size 
print(size)

# Take a screenshot
driver.save_screenshot("C:\\Desktop\\Images_png\\test1.png")
time.sleep(2)

#Crop image
x = location['x']
y = location['y']
width = location['x']+ size['width']
height = location['y']+ size['height']

im = Image.open("C:\\Desktop\\Images_png\\test1.png")
im = im.crop((int(x), int(y), int(width), int(height)))
im.save("C:\\Desktop\\Images_png\\Crop\\test1.png")

# Close the current tab
driver.close()

Thanks for your help.

Omega
  • 750
  • 1
  • 8
  • 24

2 Answers2

1

I suggest that instead of taking a screenshot of all the website, you could locate the element and take a picture of that element like this:

Let's say that you want to take a screenshot of element

from io import BytesIO
from PIL import Image

img = element.screenshot_as_png
stream = BytesIO(img)
image = Image.open(stream).convert("RGB")
image.save("imageTable.png")

Let me know if this solve your problem :P

EnriqueBet
  • 1,482
  • 2
  • 15
  • 23
  • Didn't know you could do that! The only problem is that it seems to depend on the zoom level. It does include the element, but it also includes other parts of the website. – Omega Mar 22 '20 at 02:58
  • Probably you need to find a deeper element. If this deeper element is inside of a iFrame, you will need to switch inside the frame. You can achieve that as explained in this [post](https://stackoverflow.com/questions/44834358/switch-to-an-iframe-through-selenium-and-python#44834542) – EnriqueBet Mar 22 '20 at 05:56
0

I calculated the positions manually based on the assumption that all my screenshots have the same dimensions: 1920 * 899.

#Crop image
# 1920 is the width of the screenshot
# 899 is the height of the screenshot
# 0.74 considers the zoom factor

left = (1920 - size['width']*0.74)/2
right = left + size['width']*0.74
top = 110 # Hardcoded because it's always the same value
bottom = top + size['height']*0.74


im = Image.open("C:\\Desktop\\Images_png\\test1.png")
print(im.size)
im = im.crop((left, top, right, bottom))
im.save("C:\\Desktop\\Images_png\\Crop\\test1.png")
Omega
  • 750
  • 1
  • 8
  • 24