Find and click an item from 'onclick' partial value

26,882

Solution 1

Either XPath or CssSelector would do. No need to have any looping, but straightforward locators.

driver.find_element_by_xpath(".//input[contains(@onclick, '1 Bedroom Deluxe')]")

driver.find_element_by_css_selector("input[onclick*='1 Bedroom Deluxe']")

Solution 2

You are on the right track!

buttons = driver.find_elements_by_name('booksubmit')
for button in buttons:

Yes, this exactly. You want to iterate through name = booksubmit elements and check the "onclick" attribute of each one. Here's what the rest would look like:

buttons = driver.find_elements_by_name('booksubmit')
for button in buttons:
    onclick_text = button.get_attribute('onclick')
    if onclick_text and re.search('Bedroom Deluxe', onclick_text):
        print "found it!"
        button.click()

BeautifulSoup does not help much in this case, since you still need to use selenium's methods to get ahold of the element to click on.

Solution 3

A general answer for solving these kinds of problems is using the Selenium IDE. From here, you can manually click buttons on a website and have the Selenium IDE (a Firefox plugin) record your actions. From there you can File > Export Test Case As... and choose whatever coding language you want.

Selenium Downloads page: http://docs.seleniumhq.org/download/

Selenium IDE Firefox plugin version 2.9.0 http://release.seleniumhq.org/selenium-ide/2.9.0/selenium-ide-2.9.0.xpi

EDIT: Sometimes you might actually be finding the correct element, but the webdriver tries to find it before it's there. Try adding this line after you create your webdriver:
In Python:
driver.implicitly_wait(10)

This tells your webdriver to give itself more time to try to find the object. It does not add a 10 second wait, but says keep looking for 10 seconds. If it finds the element before 10 seconds, it will continue on as normal.

Share:
26,882
crookedleaf
Author by

crookedleaf

[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo *Click*

Updated on July 09, 2022

Comments

  • crookedleaf
    crookedleaf almost 2 years

    Is it possible to click an element through selenium by a partial value of an onclick element?

    There are multiple input items on a page, and I only need to select one with a specific string.

    Examples would be:

    <input name="booksubmit" type="button" class="searchAvailBtnSelect" value="Select" onclick="setTimeout('disableSelect()',1);bookNowSubmit('0165','1BD','000000452014022703S000016500010708F ','101400','156000','3','02/27/2014','false','false','false','false','true','false','false','EXPRESS','63','1 Bedroom Deluxe','false','AC')">
    <input name="booksubmit" type="button" class="searchAvailBtnSelect" value="Select" onclick="setTimeout('disableSelect()',1);bookNowSubmit('0165','2BD','000000452014022703S000016500010708F ','101400','156000','3','02/27/2014','false','false','false','false','true','false','false','EXPRESS','63','2 Bedroom Deluxe','false','AC')">
    <input name="booksubmit" type="button" class="searchAvailBtnSelect" value="Select" onclick="setTimeout('disableSelect()',1);bookNowSubmit('0165','1BD','000000452014022703S000016500010708F ','101400','156000','3','02/27/2014','false','false','false','false','true','false','false','EXPRESS','63','1 Bedroom Presidential','false','AC')">
    

    If you notice towards the end, there is a "1 Bedroom Deluxe", "2 Bedroom Deluxe", and "1 Bedroom Presidential". Since it is an input item, there isn't any text that I would be able to filter by, but I need to only select a specific item, such as the 2 Bedroom Deluxe.

    Is there anything I could do in the sense of:

    buttons = driver.find_elements_by_name('booksubmit')
    for button in buttons:
        if button ........
    

    something or another? I'm currently using beautifulsoup4 to also parse the html on the page and retrieve text that is associated with the item, so i don't know if that could be incorporated at all. Visually, the page is an HTML table that is in the format of:

    +--------------------------------------------------------------------+
    |    1 Bedroom Deluxe    |   $25   |   [button i don't care about]   |
    |------------------------+---------+---------------------------------|
    |    2 Bedroom Deluxe    |   $50   |   [button i'm trying to click]  |
    |------------------------+---------+---------------------------------|
    | 1 Bedroom Presidential |   $50   |   [button i don't care about]   |
    +--------------------------------------------------------------------+
    

    EDIT:

    I guess posted this too soon. Right after, a coworked came up and suggested finding the element by Xpath with:

    driver.find_element_by_xpath('//input[contains(@onclick,"1 Bedroom Deluxe")]')
    
  • crookedleaf
    crookedleaf about 10 years
    Awesome! I didn't even think of the get_attribute method and then searching it. Will definitely help in other projects. Thanks!