Selenium take element screenshot - Google Chrome - python

I'm trying to take screenshot of a <canvas> tag element from google chrome using selenium web driver and python.
I tried using the below code,
driver.find_element_by_css('#canvas-xyz').save_screenshot('canvas.png')
It returned
AttributeError: 'WebElement' object has no attribute 'save_screenshot'
I also tried this in dev tools,
document.querySelector('#canvas-xyz').toDataURL()
It returned the following DATA URI, which is empty.
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABq8AAAAhCAYAAABHnTGeAAAEQ0lEQVR4Xu3ZMREAAAwCseLfdG38kCrgUjZ2jgABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBEYJEcYhAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBA445USECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIZASMV5lXCEKAAAECBAgQIECAAAECBAgQIECAAAECBAgQIGC80gECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIGMgPEq8wpBCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEjFc6QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgkBEwXmVeIQgBAgQIECBAgAABAgQIECBAgAABAgQIECBAgIDxSgcIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQyAsarzCsEIUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQMF7pAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAQEbAeJV5hSAECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQLGKx0gQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBDICBivMq8QhAABAgQIECBAgAABAgQIECBAgAABAgQIECBAwHilAwQIECBAgAABAgQIECBAgAABAgQIECBAgAABAhkB41XmFYIQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgYr3SAAAECBAgQIECAAAECBAgQIECAAAECBAgQIEAgI2C8yrxCEAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAeOVDhAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECGQEjFeZVwhCgAABAgQIECBAgAABAgQIECBAgAABAgQIECBgvNIBAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBjIDxKvMKQQgQIECAAAECBAgQIECAAAECBAgQIECAAAECBIxXOkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIJARMF5lXiEIAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQICA8UoHCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEMgLGq8wrBCFAgAABAgQIECBAgAABAgQIECBAgAABAgQIEDBe6QABAgQIECBAgAABAgQIECBAgAABAgQIECBAgEBGwHiVeYUgBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECxisdIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQyAgYrzKvEIQAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQMB4pQMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIZAeNV5hWCECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIGK90gAABAgQIECBAgAABAgQIECBAgAABAgQIECBAICPwDiwAIhIPZYcAAAAASUVORK5CYII=
Is it possible to take screenshot of an element using chromedriver and selenium in python. I am aware that chrome dev tools allows us to take screenshot of a particular element. Even if it is a JavaScript method also i can get the data URI using driver.execute_script() command.

WebElement doesn't have save_screenshot. You can use screenshot_as_png (property) and save it
element = driver.find_element_by_css('#canvas-xyz')
scrrenshot = element.screenshot_as_png
with open('canvas.png', 'wb') as f:
f.write(scrrenshot)

Use WebElement.screenshot()method:
def screenshot(self, filename):
"""
Saves a screenshot of the current element to a PNG image file. Returns
False if there is any IOError, else returns True. Use full paths in
your filename.
:Args:
- filename: The full path you wish to save your screenshot to. This
should end with a `.png` extension.
:Usage:
element.screenshot('/Screenshots/foo.png')
"""
So, in your example, that would be:
driver.find_element_by_css('#canvas-xyz').screenshot('canvas.png')

Related

Generate and download tsv from a website (with python)

I have this website and want to write a script which can execute a code which gives the same output as clicking on 'Export' -> 'Generate tsv' -> Wait to generate -> 'Download'.
The endgoal is to use this for a list of approx. 1700 proteins which I have in .txt (so extract a protein, in this case 'Q9BXF6' and put it in the url: https://www.ebi.ac.uk/interpro/protein/UniProt/Q9BXF6/entry/InterPro/#table) and download all results in .tsv files.
I tried inspecting the 'Export' button but the sourcecode wasn't illuminating (or I didn't know where to look). I also tried this:
r = requests.get('https://www.ebi.ac.uk/interpro/protein/UniProt/Q9BXF6/entry/InterPro/#table')
soup = BeautifulSoup(r.content, 'html.parser')
to locate what I need but it outputs a bunch of characters that I can't really understand.
I also tried downloading the whole page just like it is with the urllib library:
with
myurl = 'https://www.ebi.ac.uk/interpro/protein/UniProt/Q9BXF6/entry/InterPro/#table'
urllib.request.urlopen() as f:
html = f.read().decode('utf-8')
or
urllib.urlretrieve (myurl, 'interpro.txt') # although this didn't work
It seems as if all content is written somewhere else and refered to and everything I've tried outputs something stupid, but I don't know anything about html and am really new to python (I only use R).
For your first question, you can use the URL of the following element to retrieve the protein value that you require for the next problem.
href="blob:https://www.ebi.ac.uk/806960aa-720c-4958-9392-f242adee627b"
The URL is set to the href tag which you can then use it to make the request to download the file. You can also obtain this by right-clicking on the download button for TSV and clicking Inspect-Element you will then be able to see the presence of this href tag.
Following that, download by doing e.g.
import urllib.request
url = 'https://www.ebi.ac.uk/806960aa-720c-4958-9392-f242adee627b'
urllib.request.urlretrieve(url, '/Users/abc/Downloads/file.tsv') # any dir to save
with open("/Users/abc/Downloads/file.tsv") as file_in:
for line in file_in:
#here make your calls for your second problem.
You can also use a Web-Automator such as selenium to gracefully solve this problem. If the latter is of interest do look into it - it's not hard.

Application().connect in PyWinAuto Cannot Find the Element I want

I am using Selenium& Chrome Webdriver and I need to upload a Image file.
Since I cannot send the file using SendKeys, I am tring to handle the windows File Browser using PyWinAuto.
So after I click the find file button using selenium, I have to use PyWinAuto to find the windows file browser that has been opened, So I have used Applications().connect.
This is the code I need help with.
app=Application().connect(title_re="Open")
app.FileUpload.Edit.SetText("screenshot.png")
time.sleep(5)
app.FileUpload.Button.click()
The Error comes on the first row of the code, Which says
ElementNotFoundError: {'title_re': 'Open', 'backend': 'win32', 'visible_only': False}
I do not understand why the Element Cannot be found.
I upload a picture of the windows File browser I need to find.
The error that you are getting, looks like it's because it cannot find an application with the title of "Open". In your screenshot, it still looks like that's a Chrome window rather than a Window Explorer window.
The best way to know, is to use a tool to find different elements, a great one is 'inspect.exe' that comes standard on windows. Instructions on how to find this are here.
I've also found that sometimes, it's needed to use Desktop() rather than Application().
I suggest using uiautomation:
import uiautomation
path = uiautomation.EditControl(Name = "File name:")
path.SetFocus()
path.SendKeys(file_path)
btn = uiautomation.ButtonControl(Name = "Open")
btn.SetFocus()
btn.Invoke()
fil = uiautomation.EditControl(Name="File name:")
fil.SetFocus()
fil.SendKeys(file_name + '{Enter}')
You can use SendKeys(file_path + file_name + '{Enter}'), but in python the '\' is not dectected as a string, so I have to split them into 2 part.
With uiautomation, it works good for me, Here is the code
path = uiautomation.EditControl(Name = "File name:")
path.SetFocus()
path.SendKeys(file) #file=filepath
btn = uiautomation.ButtonControl(Name = "Open")
btn.SetFocus()
fil = uiautomation.EditControl(Name="File name:")
fil.SetFocus()
fil.SendKeys('{Enter}')
Instead of Application(), use Desktop() as shown below.
print_control_identifiers() will print identifiers for controls and its descendants. You can use appropriate control from the output to upload your file.
from pywinauto import Desktop
app=Desktop().window(title="Open")
app.print_control_identifiers()

How to use JavascriptExecutor instead of send_keys in Python selenium

I have written a script in python using send_key to type some text in a textarea on this webpage. However, it is really slow to use send_key as my text is really chunky.
from selenium import webdriver
text = "gckugcgaygartty"
link_url ="http://www.bioinformatics.org/sms2/translate.html"
driver = webdriver.Chrome('chromedriver', chrome_options=options)
driver.get(link_url)
driver.find_element_by_tag_name("textarea").clear()
driver.find_element_by_tag_name("textarea").send_keys("gckugcgaygartty")
I then tried to replace the send_keys with execute_script() like following but it didn't work (no errors but nothing changed on the webpage), could anyone give me some advice please?
driver.execute_script("document.getElementById('main_form').getElementsByTagName('textarea')[0].click()")
driver.execute_script("document.getElementById('main_form').getElementsByTagName('textarea')[0].setAttribute('value', 'gckugcgaygartty' )")
Modification : Changed setAttribute function with value property
Use following Code :
driver.execute_script("document.getElementsByTagName('textarea')[0].value='your_lengthy_data'")
OR
driver.execute_script("document.getElementById('main_form').getElementsByTagName('textarea')[0].value='your_lengthy_data'")

open 'href' variable in a new tab

I'm using selenium and chrome webdriver with python.
I'm trying to store 'href' inside a variable ('link' for this example) and open it in a new tab.
i know how to open a dedicated website in a new tab using this way:
driver.execute_script("window.open('http://www.example.com', 'newtab')")
but using windows.open script accepts only direct text(as far as i know) and not variables.
Here is the code:
link = driver.find_element_by_class_name('asset-content').find_element_by_xpath(".//a[#class='mr-2']").get_attribute("href") #assigning 'href' into link variable. works great.
driver.execute_script("window.open(link, 'newtab')") #trying to open 'link' in a new tab
The error:
unknown error: link is not defined
Any other way i can open 'link' variable in a new tab?
You passing on a string to execute_script, so pass not a 'link' literally, but the value from the link (concatenate):
driver.execute_script("window.open('"+link+"','icoTab');")
Another way to open a tab is sending CTRL+T to the browser:
driver.find_element_by_tag_name('body').send_keys(Keys.COMMAND + 't')
driver.get(link)
As mentioned, you can find more here 28431765/open-web-in-new-tab-selenium-python
Passing the parameter in scripts is not treating as url to make it url try This one. It works for me.
driver.execute_script("window.open('{},_blank');".format(link))
Please let me know if this work.

parse directly on pure html source with selenium in python

I'm trying to test the selenium program that I wrote by giving it an HTML source as a string for some reasons such as speed. I don't want it to get the URL and I don't want it to open a file I just want to pass it a string that contains whole DIV part of that site and do parsing stuff on it.
this is part of a module that i wrote:
source = driver.page_source
return {'containers': source}
and in another module,
def get_rail_origin(self):
return self.data['containers'].find_element_by_id('o_outDepName')...
I'm trying to do parsing stuff on it but I get
AttributeError: 'str' object has no attribute 'find_element_by_id'
So how can I parse on pure HTML source without opening any file or URL
Selenium works with live HTML DOM. If you want to get source and then parse it, you can try, for instance, lxml.html:
def get_rail_origin(self):
source = html.fromstring(self.data['containers'])
return source.get_element_by_id('o_outDepName')
P.S. I assumed that self.data['containers'] is HTML source code

Categories

Resources