2

I am unable to select a particular element in this webpage for automation in Selenium (python).

These two fields, taken from the webpage, are what I'm looking for:

enter image description here

When I right-clicked and clicked on "inspect element," I found the following html markup (well, a subset of it):

<label>Client ID:</label> <db-client-combobox default-value="vm.clientId" on-select="vm.onClientSelected(clientId)" class="ng-isolate-scope"> <db-combobox placeholder="Select a client" list="clientNames" default-value="defaultValue" on-select="onClientSelected(value)" mode="longlist" class="ng-isolate-scope"> <div class="input-group combobox dropdown"> <input type="text" class="form-control ng-pristine ng-valid ng-touched" placeholder="Select a client" data-toggle="dropdown" ng-model="itemSelected" ng-change="onInputKeyUp()" ng-focus="onInputFocus()" aria-expanded="false"> <span class="input-group-addon dropdown-toggle btn" id="combobox-list" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"> <span class="caret"></span> </span> <ul class="dropdown-menu" aria-labelledby="combobox-list"> <!-- ngIf: mode == 'longlist' --> <div class="sf-viewport sf-viewport-biglist real ng-scope" ng-if="mode == 'longlist'" style="overflow: auto; max-height: 300px;"> <div style="margin: 0px; padding: 0px; border: 0px; box-sizing: border-box; height: 67912px;"> </div> </div> <!-- end ngIf: mode == 'longlist' --> <!-- ngIf: mode == 'shortlist' --> </ul> </div> </db-combobox> </db-client-combobox> </div> &nbsp; <div class="form-group"> <label>Agent ID:</label> <input type="text" class="form-control js-call-type ng-pristine ng-valid ng-touched" ng-model="vm.agentId"> </div> 

The "Client ID" field is both a drop-down and a text field (it's up to the user to choose whether said user wants to type the Client ID or select it from a drop down menu). The Agent ID is simply a text field to enter numbers.

I can't seem to select either in Selenium. To select the Client ID, for example, I've tried the following Python commands (separately):

client_id_field = browser.find_elements_by_css_selector('select') client_id_field = browser.find_element_by_css_selector("input.form-control ng-pristine ng-valid ng-touched") client_id_field = browser.find_element_by_css_selector("input.form-control.ng-pristine.ng-valid.ng-touched") client_id_field = browser.select_by_xpath('/html/body/div[1]/div/div[1]/div/div/div[1]/db-client-combobox/db-combobox/div/input') client_id_field = browser.select_by_class_name('form-control ng-pristine ng-valid ng-touched') 

Sadly, nothing seems to work, and I'm not sure why. The only other possibility I see is selecting the labels, i.e. <label>Client ID:</label> and then telling the interpreter to go to the next element and select that- though I'm not sure what the correct syntax would be.

Can anyone help?

UPDATE: after following alecxe's suggestion to try inserting

client_id_box = browser.find_element_by_xpath("//label[. = 'Client ID:']/following-sibling::db-client-combobox") 

I got the following error in the command line prompt:

selenium.common.exceptions.NoSuchElementException: Message: {"errorMessage":"Una ble to find element with xpath '//label[. = 'Client ID:']/following-sibling::db- client-combobox'","request":{"headers":{"Accept":"application/json","Accept-Enco ding":"identity","Connection":"close","Content-Length":"147","Content-Type":"app lication/json;charset=UTF-8","Host":"127.0.0.1:53214","User-Agent":"Python-urlli b/2.7"},"httpVersion":"1.1","method":"POST","post":"{\"using\": \"xpath\", \"ses sionId\": \"d67f3550-e736-11e6-a1df-2f9c010cd01f\", \"value\": \"//label[. = 'Cl ient ID:']/following-sibling::db-client-combobox\"}","url":"/element","urlParsed ":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","re lative":"/element","port":"","host":"","password":"","user":"","userInfo":"","au thority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"] },"urlOriginal":"/session/d67f3550-e736-11e6-a1df-2f9c010cd01f/element"}} Screenshot: available via screen 

Something that strikes me oddly (sorry if this sounds so naive) is that the command line says unable to find element with xpath... and then after listing the xpath I asked for, it also lists lots of other jargon that I didn't mean to ask for. Am I not making the most out of the interpreter's debugging response?

    1 Answer 1

    1

    The only other possibility I see is selecting the labels, i.e. Client ID: and then telling the interpreter to go to the next element and select that- though I'm not sure what the correct syntax would be.

    This can be achieved with a following-sibling axis:

    client_id_box = browser.find_element_by_xpath("//label[. = 'Client ID:']/following-sibling::db-client-combobox") 

    Then, once you have the client id box element, you can locate the inner input:

    client_id_input = client_id_box.find_element_by_tag_name("input") client_id_input.click() # TODO: you might not need it, please check client_id_input.send_keys("Test") 

    For the dropdown, you first probably need to open it up and then select the desired option:

    client_id_box.find_element_by_id("combobox-list").click() # open the dropdown # TODO: select option 

    Note that, to make things more reliable and to avoid timing errors, you may need to start using Explicit Waits.

    8
    • Thank you for your swift response, alecxe. I tried your suggestion to use the following-sibling axis, but I still got a strange error. I updated my question to include the error response. Would you mind checking it out? Needless to say, I'm still very new to web scraping.
      – daOnlyBG
      CommentedJan 30, 2017 at 22:06
    • @daOnlyBG sure, what if you use the WebDriverWait and presence_of_element_located expected condition? (may be a timing error)
      – alecxe
      CommentedJan 30, 2017 at 22:06
    • Sure thing. I'll give it a shot.
      – daOnlyBG
      CommentedJan 30, 2017 at 22:08
    • When coding for the expected condition, the example uses By.ID, "myDynamicElement". The element I'm looking for doesn't have an explicitly stated ID; how would you recommend I implement the condition? I was thinking to do: EC.presence_of_element_located(browser.find_elements_by_xpath("//label[. = 'Client ID:']/following-sibling::db-client-combobox"))
      – daOnlyBG
      CommentedJan 30, 2017 at 22:23
    • @daOnlyBG ah, use the By.XPATH instead.
      – alecxe
      CommentedJan 30, 2017 at 22:24

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.