I am using Selenium PhantomJS to perform headless dynamic scraping. I was able to extract all information except popups triggered by an ng-click, such as:
<button href="#" ng-click="navigation.login({edu:false})">login</button>
<a class="btn btn-primary" ng-click="login()">signup</a>
I want to get the tag that contains ng-click label, so that I can perform onclick activity and extract information from it.
The ng-click value and tag can be anything, I just want to search whether a tag contains ng-click or not, and if it is then return that tag.
I don't want to use regex or something like that.
The most simple solution is using XPath to check length of value of ng-click.
elements = driver.find_elements_by_xpath("//*[string-length(#ng-click) > 1]")
for element in elements:
element.click()
It works.
elements = driver.find_elements_by_xpath("//*[(#ng-click)]")
Related
I'm trying to find element by xpath that contains multiple variables and click on it.
I tried using :
oddsnumber = "1.18"
oddstype = "Barcelona"
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#span='"+ oddstype +"' and #span='"+ oddsnumber +"']"))).click()
With only one variable it works, but I need to use multiple in order for script to click on right element.
This is the element it should click on
<div class="gl-Participant gl-Participant_General gl-Market_General-cn3 "><span class="gl-Participant_Name">Barcelona</span><span class="gl-Participant_Odds">1.18</span></div>
<span class="gl-Participant_Name">Barcelona</span>
<span class="gl-Participant_Odds">1.18</span>
Tried to make a script that clicks on element by xpath that matches to multiple variables
You can use this xpath, which targets a div element having two span children with the requested attributes
f"//div[child::span[text()='{oddsnumber}'] and span[text()='{oddstype}']]"
Could someone please tell me how can I select a dynamic element using selenium?
I would like to select the "limit-order" element.
<div class="tab-control" id="uniqName_0_85" widgetid="uniqName_0_85">
<span data-tab="market-order" class="tab-item tab-active">Market</span>
<span data-tab="limit-order" class="tab-item">Limit</span>
<span data-tab="stop-order" class="tab-item">Stop</span>
<span data-tab="stop_limit-order" class="tab-item">Stop Limit</span>
</div>
I tried this but no luck:
btn_limit_name_xpath = '//div[contains(#class,"tab-control")]/span[2]'
btn_limit = browser.find_element_by_xpath(btn_limit_name_xpath)
btn_limit.click()
What sometimes does the job for me is copy the full xpath instead of the shorter one.
If that doesn't work either, you could try and check this out.
They show you how you can use an xpath to find a specific piece of text and select the object in that way. So in your case you could try and find it by searching for 'limit'.
I have a web page which i am automating, I can click on any other elements using xpath or name or ID, but this gets little tricky when the element which I want to click is inside label. Here is the example,
<div class="dv-widget dv-deco-def dv-sz-med dv-map-sw">
<input name="l_maps" id="grp_perc" value="0" class="map_HD dv-radio-swr" type="radio">
<label for="grp_percentage" class="dv-radio-swl" onclick="">%</label>
<input name="l_maps" id="grp_count" value="1" class="map_HD dv-radio-swr" checked="" type="radio">
<label for="grp_multiply" class="dv-radio-swl" onclick="">*</label></div>
I need to click on the radio buton with the text % on it, I tried several option using xpath and CSS and ID but nothing seems to find that element under that label. I need help on this guys please. Thank you in advance.
This is kind of a strange situation. Typically the for attribute of the LABEL matches the ID of the INPUT that it corresponds to, e.g.
<input id="name" ... >
<label for="name" ... >
But in this case it doesn't match. We can get around it pretty easily. You can search for the element that contains the % text using XPath and then find the preceding INPUT.
//label[.='%']/preceding-sibling::input
If you plan to use this elsewhere also, I would suggest that you put this into a function and pass in the LABEL text, e.g. % and feed that into the locator to click the matching INPUT.
To click on the radio button with the text as % you can use either of the following lines of code :
Using preceding :
driver.find_element_by_xpath("//label[#class='dv-radio-swl' and #for='grp_percentage']//preceding::input[1]").click()
Using preceding-sibling :
driver.find_element_by_xpath("//label[#class='dv-radio-swl' and #for='grp_percentage']//preceding-sibling::input[1]").click()
Using ancestor :
driver.find_element_by_xpath("//label[#class='dv-radio-swl' and #for='grp_percentage']//ancestor::input[1]").click()
Update
As per the first part of the xpath I have provided it correctly identifies the <label> element with text as %. See the snapshot :
Now, appending preceding makes no mistake to identify the previous <input> tag. See snapshot :
So in all means our xpath is correct. Possibly, you need to induce a waiter for the element to be clickable as follows :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#class='dv-radio-swl' and #for='grp_percentage']//preceding::input[1]"))).click()
If you are still unable to locate the element check the HTML if the element is within an <iFrame> tag and you will find a detailed discussion in How can I select a html element no matter what frame it is in in selenium?
Is there a way to get the xpath of an webelement knowing only its innerHTML value?
Say I've got a 'Save' button, which is a button with text "Save". Say that the button can change its location on the page with subsequent updates to the system, therefore changing its xpath every time.
Here is an example bit from the page source:
<button ng-click="Model.Save()" ng-disabled="Model.SavingChecklist" href="javascript:void(0)" class="btn" translate="">
<span class="ng-scope">Save</span>
</button>
I want to search the page for the innerHTML value "Save" and return the xpath (of the second line).
Note that "Save" is not a link.
Is it possible?
You can use following XPath to match any element with innerHTML="Save":
//*[text()="Save"]
or in your case:
//button/span[text()="Save"]
I have a html code that has two links but both the links have the same href value, but the onclick and the text are different.
I wasn't sure as to how to access the second link.
I tried using driver.find_element_by_link_text('text'), but I get a no such element found error.
<div id="member">
<"a href="#" onclick="add_member("abc"); return false;">run abc<"/a>
<br>
<"a href="#" onclick="add_member("def"); return false;">run def<"/a>
</div>
There are multiple options to get the desired link.
One option would be to get use find_element_by_xpath() and check onclick attribute value:
link = driver.find_element_by_xpath('//div[#id="member"]/a[contains(#onclick, "add_member(\"def\")")]')
link.click()
Another one would be to simply find both links and get the desired one by index:
div = driver.find_element_by_id('member')
links = div.find_elements_by_tag_name('a')
links[1].click()
Which option to choose depends on the whole HTML content. Hope at least one of two suggested solutions solves the issue.