1

I need to build a script to automate action on this website that is builded using PHP.

For that, I'm using the Selenium package for python.

So I instantiate the browser and made login using the xpath to get the elements

browser = webdriver.Chrome()
browser.get('https://openboxmobile.redicom.cloud/login.php')
username = browser.find_element_by_xpath('//*[@id="_utilizador"]')
password = browser.find_element_by_xpath('//*[@id="_password"]')
username.send_keys(USERNAME)
password.send_keys(PASSWORD, Keys.ENTER)

The problem

After log-in on the page, I need to click on a input type="button", so I'm trying to get the element using xpath again.

product_import = browser.find_element_by_xpath('//*[@id="but_2"]')

but the following exception was raised.

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="but_2"]"}
  (Session info: chrome=94.0.4606.71)

What I already tryed

I tryed to get the element using full x-path and id

I also printed the base64 image after loging to check if the page was updating and it is.

IMAGE OF PAGE HTML

enter image description here

Update

I looked at some other questions and I found this, so I tried to run the following code, but a TimeoutException was raised.

WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[@id="imain"]')))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="but_2"]'))).click()

Update 2

iframe = driver.find_element_by_xpath('/html/body/iframe')
driver.switch_to.frame(iframe)
product_import = driver.find_element_by_xpath('//*[@id="but_2"]')

this code crashed on the product_import line, so, apparently, the driver switched to the correct iframe, but selenium.common.exceptions.NoSuchElementException: was raised

SOLUTION

I used chromium to get full xpath of two frames that was wrapping my application (I discovered that by getting the full xpath of my button and I see that was too short, that because he was wrapped).

So I ran the following code

WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "/html/body/iframe")))
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "/html/frameset/frameset/frameset[2]/frame[1]")))
import_input = driver.find_element_by_xpath("/html/body/div[3]/div[3]/table/tbody/tr/td[1]/input[2]")
import_input.send_keys(Keys.ENTER)

If the button was actually a button and not an input type button he could be click by using this command.

WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[3]/div[3]/table/tbody/tr/td[1]/input[2]"))).click() 
Bodok
  • 336
  • 2
  • 13

1 Answers1

1

The input tag is in iframe, in Selenium you will have to switch to iframe first and then you can interact with the input tag.

Please switch it like this :

WebDriverWait(browser, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "mainframe")))
product_import = browser.find_element_by_xpath('//*[@id="but_2"]')

You will have to import these :

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

You will also have to make sure that the input is under just this iframe. There could be a possibility of nested iframes as well.

Also, iframe id has to be unique in HTMLDOM to make this to work.

PS : Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.

Steps to check:

Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.

Also, I would say if id is unique please use id not xpath for this :

browser.find_element_by_xpath('//*[@id="but_2"]')

A way better approach would be with WebDriverWait element_to_be_clickable. Something like this :

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, "but_2"))).click()
cruisepandey
  • 28,520
  • 6
  • 20
  • 38
  • I'm trying to make work! – Bodok Oct 09 '21 at 17:23
  • The direct catch on but_2 raised a TimeoutException and the following line raised the same error as before (please see if the "imain" part is correct) => `WebDriverWait(browser, 20).until(EC.frame_to_be_available_and_switch_to_it((By.ID, "imain")))` – Bodok Oct 09 '21 at 17:27
  • There is just one iframe on the HTML – Bodok Oct 09 '21 at 17:28
  • No you should use `mainframe` not `imain`. The one I have given in my solution. – cruisepandey Oct 09 '21 at 17:49
  • Again the TimeoutExeption was raised, I ran the same command as you typed. This page gave other two – Bodok Oct 09 '21 at 17:56
  • 1
    I saw your update this this works `iframe = driver.find_element_by_xpath('/html/body/iframe') driver.switch_to.frame(iframe) product_import = driver.find_element_by_xpath('//*[@id="but_2"]')`, and `but_2` is throwing no such element then you would need to check in HTML DOM, if it is representing the right element. `Steps to check:` are already mentioned in my solution above. – cruisepandey Oct 09 '21 at 18:13