5

I was curious if there was a way to find an element using Selenium and Python 2.7 by multiple "keywords" in any order. Allow me to explain using an example:

keyword1 = raw_input("Keyword: ").lower().title()
keyword2 = raw_input("Keyword: ").lower().title()

    try :
        clickOnProduct = "driver.find_element_by_xpath(\"//*[contains(text(), '" + keyword1 + "')]\").click()"
        exec(clickOnProduct)

This is just a snippet of the code, but how could I incorporate this to look for an element that contains both of these keywords (keyword1, keyword2) in any order? It sounds easy in principle and it probably is, but I am having a hell of a time trying to get this. Any suggestions would be greatly appreciated, thanks.

Daniel Iverson
  • 119
  • 1
  • 10

1 Answers1

11

You can dynamically construct the XPath expression using or and contains():

keywords = [keyword1, keyword2, ... ]
conditions = " or ".join(["contains(., '%s')" % keyword for keyword in keywords])
expression = "//*[%s]" % conditions

elm = driver.find_element_by_xpath(expression)

If, for example, keyword1 would be hello and keyword2 would be world, the expression would become:

//*[contains(., 'hello') or contains(., 'world')]

If you want to also handle both lower and upper case, you would need to use translate(), see more in this relevant thread:

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • I still seem to be having trouble. The expression looks like this: `//*[contains(., 'Coat') or contains(., 'Car')]` but it still can't find an element that contains the text "Car Coat". – Daniel Iverson Apr 27 '16 at 18:55
  • 1
    Got it! Thank you so much, was a simple mistake on my part. I fixed my problem by changing `".join(["contains(., '%s')"` to `.join(["contains(text(), '%s')"`. Thanks for the help! – Daniel Iverson Apr 27 '16 at 18:58