3

I am trying to pass arguments to a search text in a HTML code using Selenium in Python:

I am working on the following HTML code:

</form><form class="search-box-inner">
    <div class="input-container">
        <input type="text" class="typeahead search-box-input left" autocomplete="off" placeholder="Search ratings, research, analysts, and more..." maxlength="900"></div>
</form>

The code does not have id or name. It has elements by class only.

I tried the following

self.driver.find_elements_by_class_name('search-box-inner').send_keys("HSBC Bank plc")  

But I am getting the following error:

AttributeError: 'list' object has no attribute 'send_keys'

Then I tried to fetch first element of the list and send keys by using the following code:

self.driver.find_elements_by_class_name('search-box-inner')[0].send_keys("HSBC Bank plc")

I get the following error:

"selenium.common.exceptions.WebDriverException: Message: unknown error: cannot focus element"

I have tried both the above methods for "typeahead search-box-input left" class as well. it throws the same error. following is the code I used for this:

self.driver.find_elements_by_xpath("//*[@class='typeahead search-box-input left']").send_keys("HSBC Bank plc")

I again got the following error:

AttributeError: 'list' object has no attribute 'send_keys'

Then I tried to fetch the first element of the list with the following code:

self.driver.find_elements_by_xpath("//*[@class='typeahead search-box-input left']").[0].send_keys("HSBC Bank plc")  

I again got the following error:

selenium.common.exceptions.ElementNotVisibleException: Message:
element not interactable

I also tried the following way:

element = wait.until(Ec.visibility_of_element_located((By.XPATH, "//*[@placeholder='Search ratings, research, analysts, and more...']")))

But could not sent the argument/keys to the search bar.
Any suggestions will be really helpful.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Nidhi Arora
  • 85
  • 1
  • 1
  • 9
  • 1
    sorry but you putted in your HTML, the input filed is class="typeahead search-box-input left", if you want select class="search-box-inner" after you have to get its 2 child – Carlo 1585 Feb 21 '19 at 13:24
  • Hi Carlo, I tried with this class as well "typeahead search-box-input left", but still it didn't work. – Nidhi Arora Feb 21 '19 at 15:09
  • very strange... are u able to add an ID and try again? otherwise select the father object and print it to see what u get, then select the child and try again to print what u have until u get the text field ;) – Carlo 1585 Feb 21 '19 at 15:17

4 Answers4

4

find_elements_by_xpath returns a list of webelement so that is the reason you cant use the send_keys method directly on that. You need to use find_element_by_xpath or find_elements_by_xpath("xpathExpression")[0] if you need to use send_keys on the element.

Please try the below suggestions to solve your problem:

  1. Try the xpath self.driver.find_element_by_xpath("//div[@class='input-container']") instead of the xpath you are using.

  2. Even after using the above xpath if you get ElementNotVisibleException then please check if the element is in iframe, if yes, then switch to the iframe and then use send_keys on the element.

    To switch to iframe you can use the property selenium.webdriver.remote.webdriver.WebDriver.switch_to: driver.switch_to.frame(driver.find_element_by_tag_name('iframe')) and then send_keys on the element using the mentioned xpath and if you want to switch back to the default content, you can use driver.switch_to.default_content()

0 _
  • 10,524
  • 11
  • 77
  • 109
Sameer Arora
  • 4,439
  • 3
  • 10
  • 20
  • Thanks Sameer. I tried this way, although I was able to get the webelement but I was not able to pass any keys to it. It was again giving me "ElementNotVisibleException". Then I checked if the element is in frame, but that is also not the case. Please let me know if I am missing something at my end. Thanks. – Nidhi Arora Feb 21 '19 at 15:06
  • And try to put some wait before fetching the element, should work fine then. – Sameer Arora Feb 21 '19 at 15:16
  • @NidhiArora did you check with the new xpath, did it work ? – Sameer Arora Feb 22 '19 at 08:52
  • Done :) Thanks! – Nidhi Arora Feb 24 '19 at 17:51
  • @NidhiArora How did you solve this? I am facing the same problem. I am able to get the webelement but I was not able to pass any keys to it. Even it is not in the iframe. Also included time.sleep(5) before fetching the element – Priya Nov 11 '20 at 11:08
1

Why not use a css selector e.g.

.find_element_by_css_selector(".search-box-input").send_keys 

You could extend the selector, for example, with:

.search-box-input[placeholder^='Search ratings']
QHarr
  • 83,427
  • 12
  • 54
  • 101
1

I would use this stretch:

    #Importing libs
    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    
    #Look for the class
    search_box = driver.find_element_by_class_name("typeahead search-box-input left")
    
    #Write what we be searched#
    search_box.send_keys('What will be searched')

    #Submit the text
    search_box.send_keys(Keys.RETURN)

DrSciencer
  • 11
  • 2
0

As per the HTML you have provided it is pretty clear that there are multiple <form> nodes present within the HTML DOM.


Analizing the errors

  • First attempt: self.driver.find_elements_by_class_name('search-box-inner') would return a List so you can't invoke send_keys() and you see the error as AttributeError: 'list' object has no attribute 'send_keys'
  • Second attempt: self.driver.find_elements_by_class_name('search-box-inner')[0] will identify the <form> node which can't be in focus so you can't invoke send_keys() and you see the error as WebDriverException: Message: unknown error: cannot focus element"
  • Third attempt: self.driver.find_elements_by_xpath("//*[@class='typeahead search-box-input left']") would again return a List so you can't invoke send_keys() and you see the error as AttributeError: 'list' object has no attribute 'send_keys'
  • Forth attempt: self.driver.find_elements_by_xpath("//*[@class='typeahead search-box-input left']").[0] wasn't a valid Locator Strategy

Solution

To pass a character sequence to desired element you can use either of the following solution:

  • Using CSS_SELECTOR:

    self.driver.find_element_by_css_selector("form.search-box-inner input.typeahead.search-box-input.left[placeholder^='Search ratings']").send_keys("HSBC Bank plc")
    
  • Using XPATH:

    self.driver.find_element_by_xpath("//form[@class='search-box-inner']//input[@class='typeahead search-box-input left' and starts-with(@placeholder, 'Search ratings')]").send_keys("HSBC Bank plc")
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352