1

So im making a script that clicks some buttons for me in a web browser.

Importing the selenium driver:

from selenium import webdriver
browser = webdriver.Chrome(executable_path=r'C:/Python27/Scripts/chromedriver.exe')

In this example, When i want to click on the "leave hotel" button, i can just use the css_selector and it works fine.

<div id="canvas">  
<!--<a onclick="leave_hotel();" name="go_ut" onmousedown="signature.push([Math.floor(Date.now()), 'click']);" class="hotel-button-out">-->
<a onclick="leave_hotel();" name="go_ut" onmousedown="" class="hotel-button-out">Sjekk ut <span style="font-size:0.7em" id="hotell_tid">(23 t 55 m)</span></a>
        <input type="hidden" name="t" value="cb5a965fbb0a3578344aec059afa7246">
        <input type="hidden" name="xy" id="xy" value="">
        <input type="hidden" name="ltoken" value="ea782433046a2e254b10db5045b55d02">
        <input type="hidden" value="633eacc2bbe92004ba03c9dd57ff9457" name="ttoken">
        <input type="hidden" name="jtoken" id="jtoken" value=""> 
</div>

Something like this worked fine:

browser.find_element_by_css_selector('#canvas > a').click()

But when i try to click a button within a div on another page, it does not work. the html looks like this:

<div class="canvas hotel-out">
<input class=" btn btn-block" name="enkel_knapp" onmousedown="krim_enkel_bego(2);" type="button" id="submit" value="Begå kriminaliteten!">
<input type="hidden" name="ltoken" value="e386d141ff442655d48275e0269fe1fe">
<input type="hidden" value="2b61bc54fe84d18ae5ad797826152e32" name="ttoken">
<input type="hidden" name="jtoken" id="jtoken" value="">                        
<input type="hidden" id="xy" value="nytt system (ingen koordinater)" name="xy">
</div>

But the problem is that the buttons xpath is simliar to 3 other buttons. all three buttons got the xpath "//*[@id="submit"]". I guess there is some kind of conflict here?

When i try to do it by name like this i get no respose:

browser.find_element_by_name('enkel_knapp').click()

Nothing when i do it by ID either:

browser.find_element_by_id('submit').click()

Anyone got any tips to filter by div or something?

The error i get: Pastebin

Asphaug
  • 21
  • 1
  • 7
  • can you try xpath //*[@id="submit"] in developer tool of browser to see this xpath can find only one or several elements? if find more than one elements try below code: browser.find_element_by_css_selector("div.canvas > input#submit") – yong Oct 10 '17 at 23:03
  • Are you waiting for the element to load before trying to click it? https://stackoverflow.com/questions/30339643/python-selenium-wait-for-page-to-load – Slater Victoroff Oct 10 '17 at 23:06
  • Sorry guys, was still editing the post, can you just look over and see if anything changed? i will test what you guys just wrote asap. – Asphaug Oct 10 '17 at 23:07
  • @SlaterTyranus I manually type the command into the shell, long after the site has loaded and such, if that i what you meant? Im really not a python pro, neither a selenium pro, so sorry. – Asphaug Oct 10 '17 at 23:09
  • @yong When i type "xpath //*[@id="submit"]" in console i just get "Uncaught ReferenceError: xpath is not defined at :1:1" and "browser.find_element_by_css_selector("div.canvas > input#submit")" Gave me the same error as in pastebin. – Asphaug Oct 10 '17 at 23:13
  • @Asphaug It's a bit more complicated. If you click on your first button after the page loads, then great, but when you go to the second page in that script, things might not be loaded yet. You should not be doing this in the shell. Move things to a python file, and then use the command that I sent you. The problem is that each time a new page loads, it may take a couple seconds for an element to exist. You're likely just accessing the element before it exists, so it's clicking nothing. – Slater Victoroff Oct 10 '17 at 23:14
  • @SlaterTyranus Okay, i do have the script in a python file. And when i run the module it launches a shell i can send commands in. This is the shell im using to "test" commands in. Is this wrong to do? And the command you sent, that is for adding a pause/break in the script for the page too finish loading? Or am i misunderstanding? – Asphaug Oct 10 '17 at 23:22
  • @Asphaug Generally you should try not to test things in the selenium shell. It can work, but it's very different than the code you'll have to write in the script, so it's much better to develop in python until you get very comfortable understanding what can and can't be tested in the shell. That's the general idea, but it's specifically looking for the element you've specified, so it is also a check that your selector is working properly. Either your path is wrong, or you're running it at the wrong time. If that command completes the path is right, otherwise it's wrong. – Slater Victoroff Oct 10 '17 at 23:24
  • you shouldn't try the xpath or css slector in browser 'console' Tab, look this post to learn how to do that: http://yizeng.me/2014/03/23/evaluate-and-validate-xpath-css-selectors-in-chrome-developer-tools/ – yong Oct 10 '17 at 23:27
  • @yong Cannot get it to work.. i tried to write this in console: $x(".//*[@id="submit"]") VM100122:1 Uncaught SyntaxError: missing ) after argument list – Asphaug Oct 10 '17 at 23:44
  • @SlaterTyranus Got ya. Its just that its kinda hard to run the module on new everytime to test something :/ But i just cant get it to work. – Asphaug Oct 10 '17 at 23:46
  • @yong However, when i search in "elements" i get 2 results. This seems to be right. So now we do know that there is 2 e buttons with the same xpath. – Asphaug Oct 10 '17 at 23:48
  • The first button will be clicked, did the first button is the one you wanted. if not, change code to browser.find_element_by_css_selector("div.canvas > input#submit") or browser.find_element_by_xpath(.//*[@id="submit"][2]) – yong Oct 11 '17 at 01:47
  • @yong None of the buttons get clicked, just nothing happends. None of those commands worked.. i still just get a very similiar errer to the one in pastebin. – Asphaug Oct 11 '17 at 10:37
  • Please give more of your code here, from the html you given, we can make sure we give correct xpath or css selector for the button, but you still meet NoSuchElementException, We need more code before click the button to learn what you did ahead click the button. – yong Oct 11 '17 at 11:56
  • @yong, Here is the whole website html: https://pastebin.com/8jYVVz3n If you're up for it i will more than happily teamwiever/share my screen to find the solution. – Asphaug Oct 11 '17 at 12:31
  • hey @yong, i just found out that the button im trying to click is under some kind of "tab". When i right click the "tab" and open it as a new site, i get a more advanced url, and the whole website is just that tab. When i then try to .click() the button, it works just fine. How can i make the xpath go into that "url" and click the button without me having to have diffrent sites for diffrent "tabs"? Thanks alot for the help so far! – Asphaug Oct 12 '17 at 17:40
  • What is the steps if you click the button under the "tab" manually? I don't think you need to open that tab as new site, because it's a bad user experience, the developer should not implement as that. From my experience, you should click that tab firstly to make it active. If the tab will load something when it becomes active one, add some sleep before click the button. Can you give some screenshot of your page so we can learn the relationship of the button against other elements on page. Like you finally noticed the button under a "Tab" which we can know from the html code, – yong Oct 15 '17 at 13:54
  • @yong, sorry been a stressfull couple of days. https://gyazo.com/8d86305420894f3da479922b007ae4b4 This is when im at the tab "Kriminalitet". When i change to "Underståtter" https://gyazo.com/ea66d3bf01f26dd53dbb3313bb8227b7, you see the everything changes. I can change between the "tabs" with xpath, but when i want to click the button under "kriminalitet" for an example, i does not work. Cant even find the button. BUT, if i ctrl + click the tab, so it opens as a a own site, like this: https://gyazo.com/ff50f81069eccb3a25fc6de78112cd95, it works to click the button. – Asphaug Oct 20 '17 at 08:48
  • please check there are frame or iframe tag on page when you under "kriminalitet" . If so, you need to switch to the correct frame where the button inside before you click. from all above invetiage and pratice, you can find the button by xpath in devtool, but can't click it by automation, it very like there is frame on page. – yong Oct 20 '17 at 08:59
  • Yup, looks like its within a iframe. How can i find the button within a iframe then? – Asphaug Oct 20 '17 at 09:27
  • @yong, looks like "browser.switch_to.frame("hovedinnhold")" is working. – Asphaug Oct 20 '17 at 16:24

1 Answers1

1

As you mentioned in your Question that the xpath //*[@id="submit"] is not unique and similar to 3 other buttons hence we need to construct either a unique css_selector or a xpath for this button as follows:

  • css_selector

    browser.find_element_by_css_selector("div.canvas.hotel-out > input#submit").click()
    
  • xpath

    browser.find_element_by_xpath("//div[@class='canvas hotel-out']/input[@id='submit']").click()
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Still just get the same error as i do in the pastebin, or a very similar one. After a nights sleep i think that its important to mention that the site im trying to click buttons on is a php/js site, i never refresh the site or change the actuall url. I just change tabs within the same site, kindof. – Asphaug Oct 11 '17 at 10:39
  • hey @DebanjanB, i just found out that the button im trying to click is under some kind of "tab". When i right click the "tab" and open it as a new site, i get a more advanced url, and the whole website is just that tab. When i then try to .click() the button, it works just fine. How can i make the xpath go into that "url" and click the button without me having to have diffrent sites for diffrent "tabs"? Thanks alot for the help so far! – Asphaug Oct 12 '17 at 17:41
  • It just redirects me to a new .php site. – Asphaug Oct 12 '17 at 18:00
  • If we dont have browser object we can use webdriver object to access element by id. – Maddy8381 Feb 19 '21 at 14:54
  • 1
    @Maddy8381 Here the object referred as `browser` is not a browser type object, but actually the webdriver object. A lot of newbie users tends to name the webdriver object as `browser`. – undetected Selenium Feb 19 '21 at 18:26