I want to click a three way toggle using selenium with python.The html element Ids are dynamic. So I have tried with an XPath where class contains a specific text! But I seeing 'element not found'/'element not visible' whole day!
I've tried with below line of code but no help.
browser.find_element_by_xpath("//*[contains(#class,'switch switch-three toggle ios') and contains(text(),'Available')]").click()
Here is the HTML code of the page and I want to click on - 'Available'
<label class="switch switch-three toggle ios" id="radio8526" onclick="" style="float: left; width: 300px; height:15px; margin-right: 20px;margin-left: 20px;">
<input id="available8526" value="available" onclick="setVersioningIdFun('8526');document.getElementById('toggleStateButton').click();;" name="onoffswitch8526" type="radio">
<label for="available8526" onclick="">Available</label>
<input id="unavailable8526" value="unavailable" onclick="setVersioningIdFun('8526');document.getElementById('toggleStateButton').click();;" name="onoffswitch8526" type="radio">
<label for="unavailable8526" onclick="">Unavailable</label>
<input id="archived8526" value="archived" onclick="setVersioningIdFun('8526');document.getElementById('toggleStateButton').click();;" name="onoffswitch8526" type="radio" checked="">
<label for="archived8526" onclick="">Finalised</label>
<a class="slide-button"></a>
</label>
From w3c documentation You can use this to solve your problem
browser.find_element_by_css_selector('input[id^="available"]').click()
You can just use the value attribute, e.g.
input[value='available']
You might need to add a wait for clickable to make sure the page has loaded. See this link for more info and some examples.
Related
Q: What XPath or CSS selector I can use to select 2nd <div class="checkbox">?
I have tried to use:
XPath - //div[#class="checkbox"][2]
CSS - div.checkbox:nth-child(2)
However none of them worked on chrome developer tool.
I can use $x('//div[#class="checkbox"]') to see all three checkboxes
I can use $x('//div[#class="checkbox"]')[0] to specify the 1st div.checkbox
I can use $x('//div[#class="checkbox"]')[1] to specify the 2nd div.checkbox
Here's an example of my HTML Structure
<div class="fs">
<div class="f">
<div class="checkbox">
<input type="radio" value="A">
<label for="A">A</label>
</div>
</div>
<div class="f">
<div class="checkbox">
<input type="radio" value="B">
<label for="B">B</label>
</div>
</div>
<div class="f">
<div class="checkbox">
<input type="radio" value="C">
<label for="C">C</label>
</div>
</div>
</div>
Rather than trying to find the second element by index, another possibility would be to get it by the value on the INPUT or the text in the LABEL that is contained in that DIV. A couple XPaths would be
//div[#class='checkbox'][./input[#value='B']]
//div[#class='checkbox'][./label[.='B']]
You need 2nd element from the results. Which can be done by using below
(//div[#class="checkbox"])[2]
I think CSS doesn't allow such a thing to select from a result
Since JeffC and Tarun Lalwani already suggested XPath way of doing it, I'd like to suggest a different approach.
In CSS, one can use :nth-child selector to choose 2nd <div class="f"> and grab the nested div from there. (> can be omitted)
div.f:nth-child(2) > div.checkbox
Similarly, the following works in XPath:
//div[#class='f'][2]/div[#class='checkbox']
One can choose an element based on the attribute value with CSS selector using Attribute selectors, but one cannot select the parent, unfortunately.
I'm trying to learn about web interaction, specifically using Requests.
To that end, I'm interested in using Python with Requests to download a list of car parts from OReillyAuto.com But I'm running into a hiccup.
When I browse to this url, it should show me a list of brake pads and shoes for the type of car I've specified. However, it pops up a set of radio buttons asking if I want to view parts for the left side, right side, or all parts.
I cannot for the life of me figure out how to make that selection and get the HTML that I can see in the Chrome dev tools, which contains a list of brand-names, prices, etc.
I've tried a number of things, but this is what I have now:
#import HTTP libraries
import requests
#import HTML parsing libraries
import bs4
url = 'http://www.oreillyauto.com/site/c/search/Brake+Pads+&+Shoes/C0068/C0009.oap?model=G6&vi=1432754&year=2006&make=Pontiac'
answerURL = 'http://www.oreillyauto.com/site/ConditionSelectServlet?answer=-1'
print("Making request")
session = requests.Session()
session.headers.update({'referer': url})
r = session.get(answerURL)
print(r.status_code)
oreillyList = bs4.BeautifulSoup(r.text, "lxml")
print("Writing response...")
logfile = 'C:/Users/mhurley/Portable_Python/notebooks/' + output + '.log'
with open(logfile, 'w') as file:
file.write(oreillyList.prettify())
print("...done writing "+logfile)
I expect the log file that I write out to have about 5200 lines in it, as I do when I "View Page Source." However, I'm only getting about 3000 lines, and it looks like there are no parts in that list.
Maybe I really am getting what I think I am, but I'm not interpreting it correctly. Any tips for how to get past this dialog request?
EDIT: I suspect this is the HTML relevant to my purposes:
<div id="forcedVehicleQuestions" class="forcedUserInput" style="display: block; position: absolute; left: 50%; top: 40px; z-index: 6000; margin-left: -199px; margin-top: 0px;">
<div class="forcedContents clearfix">
<a class="btn-remove" onclick="closeForced('Search','question');">
<svg><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#shape-remove"></use></svg>
</a>
<form name="forcedQuestionsForm" id="forcedQuestionsForm">
<h2 class="sans">
More Product Info Required
</h2>
<p id="questionText" class="questionText">
Brake Pads - Position
</p>
<div id="forceQuestionsRadio">
<div class="form-row">
<label class="questionRadio checkbox-radio" id="questionRadio" for="Front">
<input type="radio" id="Front" name="answer" value="10219">
Front
</label>
</div>
<div class="form-row">
<label class="questionRadio checkbox-radio" id="questionRadio" for="Rear">
<input type="radio" id="Rear" name="answer" value="10290">
Rear
</label>
</div>
<div class="form-row">
<label class="questionRadio checkbox-radio" id="questionRadio" for="Show all">
<input type="radio" id="Show all" checked="" name="answer" value="-1">
Show all
</label>
</div>
</div>
<input id="questionSubmit" type="button" class="btn btn-green btn-shadow" value="Continue" onclick="setQuestionAnswer('Brake Pads - Position',document.forms['forcedQuestionsForm'].elements['answer'],'Show all');">
<div id="forcedVehicleQuestionsLoading" class="loading load-sm">
<div class="spinner"></div>
</div>
</form>
</div>
</div>
I'm having a hard time understanding how to interact with this <form> element. How can I make the "onclick=" happen so that the form gets submitted?
You will need to use a combination of Selenium + BeautifulSoup.
First, you'll use selenium to open the webpage in a browser, select the right radio button then submit the form.
After this, use BeautifulSoup to parse the page for the brakes.
I'm currently trying to use Selenium/Python/PhantomJS to scrape the results of the form below:
http://gis.vgsi.com/newhavenct/Sales.aspx
It looks like when I try to click on the search button, I get an ElementNotVisibleException error.
My code:
self.driver.find_element_by_id("MainContent_btnSearch").click()
After some digging online, it seems like the button may be hidden. Indeed, here is the relevant HTML code from the search page:
<input type="button" value="Search!" class="btn btn-primary searchTrigger" style="width: 200px;" />
<input type="submit" name="ctl00$MainContent$btnSearch" value="Search" id="MainContent_btnSearch" style="width: 200px; display: none;" />
<div id="MainContent_ctl00" style="display:none;">
</div>
I tried preceding my previous code with a click of the searchTrigger, but this is still not working:
self.driver.find_element_by_class_name("searchTrigger").click()
self.driver.find_element_by_id("MainContent_btnSearch").click()
Any advice would be greatly appreciated!
Requested element has attribute style="display:none;", so you need to make it visible
Try to use following code:
self.driver.execute_script('document.getElementById("MainContent_btnSearch").style.display="block";')
self.driver.find_element_by_id("MainContent_btnSearch").click()
A portion of the screen is not visible by Selenium. It may be that another element lies on top of the one you are trying to click.
For me what always works without spending hours searching for the cause is to click using Javascript:
self.driver.execute_script("arguments[0].click();", elt)
where elt is a WebElement - e.g. returned by find_element_by_id(.).
Make it a function and use wherever the problem occurs.
Edit: it is a generic answer for when it happens again, but in this particular case the other answer is probably correct.
I'm unable to upload and save an image.
The following is the piece of code that facilitates file upload using the UI. At first, only the upload button is visible and once an image is selected from the uploader the save button is visible.
<td colspan="1" class="actions">
<input type="button" class="button" name="logo" id="logo-f-upload" value="Upload Image"/>
<input type="file" id="logo-upload" accept="image/*" name="logo-upload" style="display:none" />
<input type="submit" value="click to save" name="submit_logo_now" class="main submit_dm logo-save-focused" style="display: none"/>
</br>
</td>
I tried driver.find_element_by_id("logo-f-upload").send_keys(os.getcwd()+"/image_test.png")
and also
driver.find_element_by_id("logo-upload").send_keys(os.getcwd()+"/image_test.png")
but it doesn't throw any error at this stage but on the next where it says "element is not visible ..." ie. the save button. On the UI, when simulating this, the file uploader doesn't open but the file_upload button value changes to the path of the image and then breaks.
I believe this is the answer which is merely a JS hack: So the problem is that the logo-upload input has style set to display:none and due to this, selenium can't find the element. The solution that works for me is using javascript to set the style to display:block, after which using send_keys(img_path) works fine.
dr.execute_script("document.getElementById('logo-upload').setAttribute('Style','display:block')")
I'm using selenium2 webdriver with firefox.
Usually, when there is a combobox for e.g. months I set a distinct month by send_keys(monthname).
I have a special listbox this time, where I can't simply send_keys() to it (not with webdriver nor manually). I'm not a web developer, so I have no idea what the actual difference is. This is the HTML Code of that combobox:
<div class="selectArea marke" style="width: 75px; ">
<span class="left"></span>
<span class="center">Month</span>
<span class="selectButton"></span>
<div class="disabled" style="display: none; "></div>
</div>
<select name="sregisterdmc" id="sregisterdmc" class="marke outtaHere" style="width:75px" multiple="">
<option value="">Month</option>
<option value="01">01</option>
...more options...
</select>
I have no idea how I could set an option here. I found out that I can get all the option values with .find_elements_by_tag_name(), but not how I actually set such one now. Thanks in advance!
Do a click on the option element you want selected.