2

I want to click on "new order" icon in mt4 web terminal using selenium module in python

This is the code:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome('./chromedriver')
driver.get("https://www.mql5.com/en/trading")
new_order = driver.find_element_by_xpath('/html/body/div[3]/div[1]/a[1]/span[1]')
new_order.click()

And this is the error that I get:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[3]/div[1]/a[1]/span[1]"}
(Session info: chrome=86.0.4240.198)

What is the correct way to locate that button, I searched and found some ways to locate elements for selenium but I couldn't get any of them work for me.

Erfan Monemi
  • 55
  • 1
  • 6

3 Answers3

4

Looks like your page is dealing with iframes. So while the above answer has good practices, you also need to switch to the iframe:

driver.switch_to.iframe(self,frame reference)

Look for more details at https://www.techbeamers.com/switch-between-iframes-selenium-python/ or https://stackoverflow.com/a/24286392/1387701

DMart
  • 2,401
  • 1
  • 14
  • 19
2

The element with tooltip as New Order is within an <iframe> so you have to:

  • Induce WebDriverWait for the desired frame to be available and switch to it.

  • Induce WebDriverWait for the desired element to be clickable.

  • You can use the following based Locator Strategies:

    driver.get('https://www.mql5.com/en/trading')
    WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[@id='webTerminalHost']")))
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[text()='Connect to an Account']//following-sibling::div[1]/span"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@title='New Order']/span"))).click()
    
  • Note : You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    I copied the code and got no error, but the new order window wouldn't open. I added "time.sleep(10)" before the last line and then it worked. And also thanks a lot for the "Locator Strategies" link. – Erfan Monemi Nov 17 '20 at 07:24
  • 1
    Could you please explain the 3rd line for me? ...Connect to an Account... – Erfan Monemi Nov 17 '20 at 07:30
  • @ErfanMonemi `//div[text()='Connect to an Account']//following-sibling::div[1]/span` here we are looking for a `
    ` node which have the text **Connect to an Account**, then moving to it's following siblings and identifying the first `
    ` and in that `
    ` moving one step deeper to it's child `.`
    – undetected Selenium Nov 17 '20 at 07:37
  • Sorry that I'm asking aother question again, But then how can I choose an option in the new order window form the symbol drop-down menu? I wrote this code: def fast_multiselect(driver, element_id, labels): select = Select(driver.find_element_by_id(element_id)) for label in labels: select.select_by_visible_text(label) fast_multiselect(driver, 'symbol', "USDCAD") and got this error: Message: Select only works on – Erfan Monemi Nov 17 '20 at 08:16
  • @ErfanMonemi Can you raise a new question as per your new requirement please? Would be glad to help you out. – undetected Selenium Nov 17 '20 at 08:18
1

You can use a different xpath:

new_order = driver.find_element_by_xpath('//a[@title="New Order"]')

But I would suggest By, WebDriverWait, and expected_conditions:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome('./chromedriver')
driver.get("https://www.mql5.com/en/trading")
time.sleep(5)
iframe = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//iframe[@id="webTerminalHost"]')))
driver.switch_to.frame(iframe)
new_order = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//a[@title="New Order"]')))
new_order.click()
Jortega
  • 3,616
  • 1
  • 18
  • 21
  • Thank you so much.I entered the code you suggested and got this error: ...TimeoutException... Then I changed the value 10 to 40 (I'm not sure what that is) and got the same error. I wrote another code: from selenium import webdriver driver = webdriver.Chrome('./chromedriver') driver.get("https://www.mql5.com/en/trading") result = False while result == False: try: new_order = driver.find_element_by_xpath('//a[@title="New Order"]') new_order.click() result = True except Exception as e: print(e) print("done") and I get this: ....no such element.... – Erfan Monemi Nov 16 '20 at 18:11
  • the 10 is the seconds the page will wait. Increase that to wait longer (as you did) – DMart Nov 16 '20 at 18:46
  • @Erfan Monemi there is an iframe but there is also a popup that will cause `ElementClickInterceptedException` that goes away after a few seconds. See the updated answer. – Jortega Nov 16 '20 at 19:07
  • Thank you so much for the update, I copied the updated code and got no error, but the new order window wouldn't open. I added "time.sleep(5)" before the last line and then it worked. Thank you so much – Erfan Monemi Nov 17 '20 at 07:20