Take screenshot of webelement in Selenium Python and save file - python

I am trying to take a screenshot of a particular webpage element based on class name. I have followed the methods described in How to take screenshot with Selenium WebDriver, How to screenshot a specified WebElement in Selenium using Python and How to take partial screenshot with Selenium WebDriver in python?
Following are the commands and their errors:
driver.find_element_by_class_name("views-field-body").screenshot("test.png")
and driver.find_element_by_class_name("views-field-body").screenshot_as_png
Both times I get the error message as
selenium.common.exceptions.WebDriverException: Message: unknown command: session/75c3765173a9cf726d35afa7978d9b6e/element/0.5926184656216698-3/screenshot
When I try
image = driver.find_element_by_class_name("views-field-body").screenshot
this commands executes, but the image object comes out as bound method as shown in the quoted text below
bound method WebElement.screenshot of selenium.webdriver.remote.webelement.WebElement (session="75c3765173a9cf726d35afa7978d9b6e", element="0.5926184656216698-3")
How does one save this bound method to image on disk? Why are the commands not executing? Using Python 3.8, if that matters.

I think you use firefox not chrome
I found a solution
from selenium import webdriver
from PIL import Image
fox = webdriver.Firefox()
fox.get('https://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
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()
im = Image.open('screenshot.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
https://stackoverflow.com/a/37565356/8951071

Related

Why does the search image in my code doesn't work?

This is my code:
import pyautogui
images = ['colordonkergrijsDCphrasev2.png'] #the image I want it to find
while True:
for image in images: #search for the image in images
pos = pyautogui.locateOnScreen(image, region=(740,870, 50, 20)) #search on the screen for the image
if pos is not None: # this checks that the image was found
pyautogui.click(pos) # click the position of the image
I want that my code clicks on a special region when he is seeing that image.
But my code doesn't do that, my code clicks every time also when the image isn't there. The image I'm using is very similar as the background. But I added confidence = 1 and it still doesn't work
Does someone know how to fix it?
I use Python 3.9.4 64-bit.
I already read the docs but there isn't anything in there what can help me.
If you want to docs here it is: https://pyautogui.readthedocs.io/en/latest/screenshot.html

Locate an element in an image resized in Python

I'm create a project in Python using PyAutogui and I need to locate an object on the screen. First of all I crop a screenshot, and after that, I use pyautogui.locateOnScreen('element.png') for found the location. The problem is, the element sometimes is resized so this method can't found it. I tried use confidence but not work properly with that. How can i locate that element using pyautogui or something different?
This is my code:
png = ["Andrew","David","Emma","Jay","Jesse","Josh","Mickey"]
screen = pyautogui.screenshot(region=(x+1,y+1,1281,751))
for element in png:
if(pyautogui.locateOnScreen(element + '.png',confidence=0.7) != None):
print("Find " + element)

Selenium, Download Dynamic Captcha, Python

Because of the need to check like 100+ registration numbers, I decided to create a script which will do this for me, as I need to test these often.
The idea is that I have to visit the following website:
https://www.anaf.ro/inactivi/index.jsp
Where I input a registration number in the first field, and I have to input the captcha in the second. The captcha is quite easy to solve, and it is straight forward, as there are already available libraries for python, but the problem that I am facing is that the "src" attribute of the image, goes to a dynamic url.
Is there any way of saving the image which is displayed when using the .get on the webdriver?
This is how I am trying to solve the problem:
from captcha_solver import CaptchaSolver
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("https://www.anaf.ro/inactivi/index.jsp")
time.sleep(5)
elem = driver.find_element_by_name('inputCui') # Find the first input box
elem.send_keys('17741254') # Input the desired code
Or maybe, if someone has another idea on how I can approach the problem, I am open to suggestions.
Ok, so I managed to solve it, I will simply take a screenshot of the page, then crop it, after that I will decode the captcha. Here is the code for those interested:
def get_captcha(driver, element, path):
location = element.location
size = element.size
driver.save_screenshot(path)
image = Image.open(path)
left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']
image = image.crop((left, top, right, bottom))
image.save(path, 'png')
img = driver.find_element_by_xpath("//img[1]")
get_captcha(driver, img, "captcha.png")

HTML snapshots using the selenium webdriver?

I am trying to capture all the visible content of a page as text. Let's say that one for example.
If I store the page source then I won't be capturing the comments section because it's loaded using javascript.
Is there a way to take HTML snapshots with selenium webdriver?
(Preferably expressed using the python wrapper)
Regardless of whether or not the HTML of the page is generated using JavaScript, you will still be able to capture it using driver.page_source.
I imagine the reason you haven't been able to capture the source of the comments section in your example is because it's contained in an iframe - In order to capture the html source for content within a frame/iframe you'll need to first switch focus to that particular frame followed by calling driver.page_source.
This code will take a screenshot of the entire page:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('https://dukescript.com/best/practices/2015/11/23/dynamic-templates.html')
driver.save_screenshot('screenshot.png')
driver.quit()
however, if you just want a screenshot of a specific element, you could use this:
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()
Where the WebElement is the Element you're chasing. of course, this method requires you to import from base64 import b64decode and from wand.image import Image to handle the cropping.

How to remove black space from png data pulled from selenium?

I have the following png binary data that I was able to pull from a page utilizing selenium with the following code:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=39713077')
data = driver.get_screenshot_as_png()
However, the image looks like the following and I'd like to remove the black space around it:
The image is located here: http://www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=39713077
Is there a way to remove the black space utilizing the binary data or get selenium to pull only the image and not the black background?
I've tried to utilize Pil, but I've only found ways to remove white space and not black space, plus it's difficult to turn it back to binary data, which I need.
I've also looked into the PNG Module, but I couldn't figure out how to turn it back to binary as well.
One solution would be to directly get the screenshot of the image:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=39713077')
element = driver.find_element_by_css_selector("img")
image = element.screenshot_as_png()
But unfortunately Firefox doesn't yet implement this feature.
Another way would be to crop the screenshot to the targeted element:
import StringIO
from selenium import webdriver
from PIL import Image
driver = webdriver.Firefox()
driver.get('http://www.polyvore.com/cgi/img-thing?.out=jpg&size=l&tid=39713077')
element = driver.find_element_by_css_selector("img")
rect = driver.execute_script("return arguments[0].getBoundingClientRect();", element)
screenshot = driver.get_screenshot_as_png()
img = Image.open(StringIO.StringIO(screenshot))
img_cropped = image.crop((rect['x'], rect['y'], rect['width'], rect['height']))
img_cropped.save('screenshot.png')

Categories