I'm using the below code to get the current element at a cursor position, even if that element is within several iframes. I have two questions though.
- Are all iframes located within an "iframe" tag as would be needed for the below code to work? If not, is there a more accurate way to do what I'm trying to do below?
- How can I define the current iframe so that I can reliably return that identifier and find the same iframe next time the program is run? The element ID and session ID change each time the program is run, so if I were to manually save the iframe and use it to driver.switch_to.frame(element) next time the program ran, I know it wouldn't find it. So how can I make sure I'm in the correct iframe when locating an element after finding it this way?
Edit: To clarify, I'm attempting to create a script that works universally with any website, so the HTML of the website in this code would not be useful to include. That's why I wanted to know if all websites with iframes must use an "iframe" tag, or if there are some websites that this approach wouldn't work?
from selenium import webdriver
from tkinter import *
from pynput import mouse
from pynput.mouse import Listener
import time
def CheckRightClick(x, y, button, pressed):
if button == mouse.Button.right:
if pressed:
# Browser window position calculation script
coordinate_script = """
var X, Y;
if (window.screenY)
{
X = window.screenX;
Y = window.screenY + 124;
}
else
{
var Elem = document.documentElement;
if (!Elem.clientHeight) Elem = document.body;
X = Elem.scrollLeft;
Y = Elem.scrollTop;
}
return new Array(X, Y);
"""
print('Getting element')
driver.switch_to.default_content()
winPos = driver.execute_script(coordinate_script)
# actual element position in browser
x -= winPos[0]
y -= winPos[1]
driver.implicitly_wait(30)
element = driver.execute_script("""
return document.elementFromPoint(arguments[0], arguments[1]);
""", x, y)
# element = findElement(x, y)
deepestElement = None
if element is None:
print('current cursor position might be wrong')
return
if element is not None:
print(" id=> ", element.get_attribute("id"), "\n tagName=> <", element.tag_name, ">", "\n text=> ", element.text, "\n\r")
if element.tag_name == "iframe":
# get iframe element position. it will return {top: , left:, x: , y: , width: , height}
elementPos = driver.execute_script("""
var element = document.elementFromPoint(arguments[0], arguments[1]);
if(element !== null)
return element.getBoundingClientRect();
else
return null;
""", x, y)
# actual element postion in the iframe.
x -= elementPos['left']
y -= elementPos['top']
driver.switch_to.frame(element)
deepestElement = driver.execute_script("""
return document.elementFromPoint(arguments[0], arguments[1]);
""", x, y)
else:
deepestElement = element
if deepestElement is not None:
print("deepest element:\n id=> ", deepestElement.get_attribute("id"), "\n tagName=> <", deepestElement.tag_name, ">", "\n text=> ", deepestElement.text, "\n\r")
print('Element at cursor is ', deepestElement, "\n\r")
#deepestElement.click()
# click_window.event_generate("<<quit>>")
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
# driver = webdriver.Chrome(options=options, executable_path=r'./chromedriver_90.exe')
driver = webdriver.Chrome(options=options,executable_path=r'C:\Users\David\Desktop\Python\chromedriver_win32'r'\chromedriver.exe')
url = 'http://store.cardsagainsthumanity.com/'
driver.get(url)
time.sleep(3)
click_window = Tk()
click_prompt = Label(click_window, text='Right click somewhere')
click_prompt.grid(row=3, column=3)
click_window.bind("<<quit>>", lambda *args: click_window.destroy())
listener = Listener(on_click=CheckRightClick)
listener.start()
click_prompt.mainloop()
listener.stop()
from How to get current iframe reliably next time program is run?
No comments:
Post a Comment