I am writing a selenium code to go to a website and click on the following element to expand its drop down list:
Now this area is comprised of two elements.
Element 1:
Element code: <b class="icon" id="handler2"></b>
Full Xpath: /html/body/div[4]/div/div/div[3]/div[2]/div[2]/ul/li/ul/li/p/b
Element 2:
Element code: <p class="wrap button draggable" id="anonymous_element_1"><b class="icon" id="handler2"></b>Reports</p>
Full Xpath: /html/body/div[4]/div/div/div[3]/div[2]/div[2]/ul/li/ul/li/p
I used element 1. My selenium code is lengthy but the the line i used to click 'reports' is:
click_button=driver.find_element_by_xpath('/html/body/div[4]/div/div/div[3]/div[2]/div[2]/ul/li/ul/li/p/b').click()
It doesn't click the button though. I'm not sure why. Does anyone know how I can solve this problem?. It is worth noting that if you use element 2, then a double click is required.
Try:
click_button=driver.find_element_by_xpath('//*[#id="handler2"]').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}']]"
Here is the inspect result for the button that says +5 per day
>span class="text user-links entry-method-title ng-scope ng-binding" ng-include="::'views/entry-text/'+entry_method.entry_type+'.html'">
Click For a Daily Bonus Entry"
</span>
<div class="entry-method bonus template" data-remove-popovers="" id="em6129519" ng-class="{expanded: entryState.expanded == entry_method, template: entry_method.template, 'completed-entry-method': !canEnter(entry_method) && isEntered(entry_method)}" ng-repeat="entry_method in ::entry_methods">
here is the HTML given information when I inspect the link/button, I have tried to use XPath, CSS, link text, and class name and it keeps giving me an error saying it cannot identify the element. Does anyone have a suggestion for how to identify this, it is on gleam.io for a giveaway I'm trying to automate this so i don't have to log in and press this everyday. This is my first ever web interfacing project with python.
Here is my most recent try
driver.maximize_window()
time.sleep(10)
driver.execute_script("window.scrollTo(0, 1440)")
time.sleep(10)
button2 = driver.find_element_by_class_name("text user-links entry-method-title ng-scope ng-binding")
button2.click()
Similar to a previous issue, Selenium find_element_by_class_name and find_element_by_css_selector not working, you can't have spaces in your class name when using driver.find_element_by_class_name. Instead, find the element via css_selector and replace each space with a dot.
driver.find_element_by_css_selector("span.text.user-links.entry-method-title.ng-scope.ng-binding")
That'll fix what you have above, but keep in mind there are other ways to make selenium actions more reliable (eg. WebDriverWait, etc). And there may be a cleaner selector to use than the one above.
I believe the element you want to access is contained within an "iframe", thus you must first switch to iframe before you can access it using selectors.
driver.switch_to.frame(x.find_element_by_xpath("PUT IFRAME XPATH HERE"))
Essentially what I am trying to do is select just the "Reply" box which circled in red, but there are many of these in the page overall. My aim is to be able to select the first "Reply" box on every page. How can I select just the first reply box for every post (with this link just being an example)?
Currently this doesn't seem to work:
reply = driver.find_element_by_xpath("//*[#id='content']/div/div[2]/div/div/div/div[1]/article/div/aside/ul/li[1]/div/div[2]/div/ul/li[7]/button/span/img")
reply.click()
Many thanks.
First way:
The XPath to locate any of that replay buttons is
//button[#title="Reply"]
So the XPath to locate the first replay button is
(//button[#title="Reply"])[1]
So you can simply
driver.find_element_by_xpath('(//button[#title="Reply"])[1]').click()
Second way:
With the XPath above you can retrieve a list of all the replay buttons and then get the first element in the list and click on it as following:
replay_buttons = driver.find_elements_by_xpath('//button[#title="Reply"]')
replay_buttons[0].click()
You can use css_selector instead of XPath here as well:
replay_buttons = driver.find_elements_by_css_selector('button[title="Reply"]')
replay_buttons[0].click()
Inspecting the page i saw that the class name of this button is: <button class="Button Button--link">
So you can use driver.find_elements_by_class_name('Button Button--link') ,
which returns a list of all the buttons.
i was trying to click some button in the page but it changes when it is available so that mine is not working.
basically, normally it's the only one section but changes into one that contains multiple buttons. and i am aiming to click buying or another buttons when it shows but i kept failing.
when it's unavailable(to click buying or shipping button), it looks like this.
<div class="XqRGHcrncz">
<ul class="_3YA58cPPsy">
<li class="_3nAZvQO51p N=a:pcs.mylist">
<a href="javascript:void(0)" role="button" class="_3Dy-2NaoiG" aria-pressed="false">
<span class="_3nBu7xChUl"><span class="blind">찜하기</span></span>
<em class="_1c-2nfzJqH">13</em></a></li></ul></div>
but when it is available, buying button appears. everything is same but the starting from
li class, it changes a bit.
li class became
<li class="_3nAZvQO51p N=a:pcs.mylist">
and the rest changed too.
<a href="javascript:void(0)" class="OgETmrvExa">
<span class="blind">구매하기</span>
how can i make xpath to click the element that shows only available?
the main problem is that div is changing.
xpath is sometimes
//*[#id="content"]/div/div[2]/div[2]/fieldset/div[7]/ul[1]/li/a
but sometimes it is
//*[#id="content"]/div/div[2]/div[2]/fieldset/div[8]/ul[1]/li/a
so that the div[] is changing. i tried css selector to click it when it turned into new page,
buy=driver.find_css_selector(div.XqRGHcrncz)
lists = buy.find_elements_by_tag_name("ul")
if len(lists) == 2: buy.click()
but when the page is loaded to available, it is not working at all...
i was trying to use xpath like this,
while True:
lists = buy.find_elements_by_tag_name("ul")
if len(lists) == 2:
break
else:
print("구매불가")
driver.refresh()
driver.implicitly_wait(10)
and then
driver.implicitly_wait(10)
xpath='//*[#id="content"]/div/div[2]/div[2]/fieldset/div[8]/ul[1]/li/a'
driver.find_element_by_xpath(xpath).click()
but as i mentioned, the xpath is changing and there is no use. the div[number] <- this changes so that it does not working as it is wrong xpath.
what should i do?? i would be really appreciate if anyone helps me.
(just in case, this is my page that i want to click when it became available...
https://smartstore.naver.com/hwaflora/products/5192517936 thank you)
Try to find element by text, is it stable?구매하기
so the code looks like that:
driver.find_element(By.XPATH, "//span[text()='구매하기']"
or by preceding xpath feature:
driver.find_element(By.XPATH, "//a/preceding::span[text()='찜하기']")
The xpath of your element is
String button = "//li[contains(#class,'_3nAZvQO51p N')]/a"
Now, you mentioned that until it is available there are more elements below it, for example this:
String loading = "//li[contains(#class,'_3nAZvQO51p N')]/a//em"
You can wait until this element disappears. The syntax in Java is:
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until((ExpectedConditions.invisibilityOfElementLocated(By.xpath(loading))));
Now you can find and click the button element
my problem is that the first on is clicking and the second one doesnt and i dont undersatand why
WebDriverWait(rootdiv, 10).until(EC.element_to_be_clickable((By.XPATH, "//li[#onclick[contains(.,JTC)]]")))
rootdiv.find_element_by_xpath("//li[#onclick[contains(.,'JTC')]]").click()
WebDriverWait(depdiv, 10).until(EC.element_to_be_clickable((By.XPATH, "//li[#onclick[contains(.,AJU)]]")))
depdiv.find_element_by_xpath("//li[#onclick[contains(.,'AJU')]]").click()
depdiv and root div are children to look under for the certain li cause the root changes from the first to the second..
i've checked that the div is visible and in the first one, its clicking, the second time it cant find the object and im getting a time error
part of the code im trying to fed from..
<div class = "divCombo4">
<ul><li>....</li><ul>
<ul><li>...</li><ul>
</div>
and my depdiv is rooting to the find_element_by_id("divCombo4")
one of those ul li contains
onclick="selecionou('AJU', this,'.txtBusca4', 'false', 'destino', 'Estouem2', 'AJU');"
First of all, you need a dot to make the expressions context-specific. Also, the wait.until() returns a WebElement instance and you can use it instead of issuing a "find element" command again:
WebDriverWait(rootdiv, 10).until(EC.element_to_be_clickable((By.XPATH, ".//li[#onclick[contains(.,JTC)]]"))).click()
WebDriverWait(depdiv, 10).until(EC.element_to_be_clickable((By.XPATH, ".//li[#onclick[contains(.,AJU)]]"))).click()