Selenium webdriver unable to locate element in a dropdown list - python

I'm trying to click on an element in a dropdown list, and Selenium is able to locate and click the button that makes the list appear, but it doesn't seem to to be able to locate the list itself when it pops up. I have found the HTML that controls the list and tried various find_element_by methods, and none are able to locate it.
I've tried using the Select module, as well as switch_to_frame (which I'm not sure I'm doing correctly), and I've had no luck at all. Any help would be appreciated.
EDIT:
Upon further investigation, there appears to be something "off" with the HTML. When I copied the XPATH from the Chrome inspector, it gave me /html/body/div[5]/div/div/ul/li[3]/div/button, however if you notice, the first div element is div[5], but looking at the html, there are only 4 div elements that are children of the body. Also, when I copy the CSS Selector, I get body > div:nth-child(13) > div > div > ul > li:nth-child(3) > div > button, but there are only 12 total children of the body. Even stranger is the fact that both leaving these locators as they are and attempted to correct for them yield the same results, which is the error.
Here is my code:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
browser = webdriver.Chrome()
url = <url>
browser.get(url)
export1 = browser.find_element_by_xpath("//*[#id=\"react-main-content\"]/div[1]/section/div[1]/div[3]/div[2]/div/button")
time.sleep(1)
export1.click()
# This is the element it's unable to locate
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[4]/div/div/ul/li[3]/li/button")))
# Execution never reaches this point
export2 = browser.find_element_by_xpath("/html/body/div[4]/div/div/ul/li[3]/li/button")
export2.click()
Here is the HTML (I can't get it to format correctly, so here's a screenshot. The Highlighted section is the drop down I'm looking for):
Here is the webpage with the dropdown open and the element in the dropdown I'm trying to locate highlighted.

There seems to be a mistake in an xpath. you have already traversed through the list and you need not do it again. Try this one instead.
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, "/html/body/div[4]/div/div/ul/li[3]/button")))

I figured it out. Silly me assumed that the HTML from the website being opened in one browser window would match the HTML from the browser window Selenium opens (and seeing as I used the HTML from that same window to locate several other elements, why wouldn't I?). That, however, was not the case.
After pausing execution of my program and examining the HTML of the website in the browser window Selenium opens, I noticed that the location of the element I'm trying to locate is different, so I copied the XPATH from the Selenium browser window and the issue is now resolved.

Related

python selenium: clicking buttons with various html element/css attributes

i'm trying to create python automation scripts using selenium to make appointment times, however i'm having some trouble with clicking on certain elements. to confirm an appointment the steps are going to the webpage > selecting the date > selecting the time > hitting confirm
this is what i've got so far:
driver = webdriver.Chrome()
driver.get('<url.date>') -- this works
driver.find_element(By.ID,'corresponding time id').click() -- this works
driver.find_element(By.DATA-TEST-ID,'order_summary_page-button-book').click() -- this is where i'm struggling
i've also tried doing it by the button class, using the css selector and looking for 'Reserve Now' text, and using the xpath
when i do it by xpath, i get the error NoSuchElementException
i tried adding a webdriver wait function but that didn't seem to work either.
the appointment times are really hard to get, so i'd rather not but any wait times into the code so it can execute and book as soon as slots open
here are the elements:
https://i.stack.imgur.com/S62kR.png
any help is appreciated!
Selenium doesn't have option to identify the element by DATA-TEST-ID locator.
In this case You have to use either by xpath or css selector
driver.find_element(By.XPATH,'//button[#data-test-id="order_summary_page-button-book"]').click()
OR
driver.find_element(By.CSS_SELECTOR,'button[data-test-id="order_summary_page-button-book"]').click()
Ideally you should use explicit wait to click on the element.
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, '//button[#data-test-id="order_summary_page-button-book"]'))).click()
you need following imports.
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

Issues with Selenium and a Single Page Application (Ember.js)

I just started trying to learn to write python code today. I am trying to make a web scraper to do some stuff, but i am having trouble getting selenium to click on the specific boxes/places to get to the correct page. Because it uses Ember.js, it is a Single Page Application. This throws things off a little. I found some stuff on stackoverflow about it, but i wasnt able to get it to work. I keep getting the "NoSuchElementException" error. Here is my code
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
PATH = r'C:\Users\dme03\Desktop\desktop\webdrivers\chromedriver_win32\chromedriver.exe'
driver = webdriver.Chrome(PATH)
driver.get('https://thedailyrecord.com/reader-rankings-interface/')
time.sleep(15)
mim = driver.find_element(By.XPATH, '//img[#src="//media.secondstreetapp.com/1973100?width=370&height=180&cropmode=Fill&anchor=Center"]/parent::div')
mim.click
For the XPATH, I had to select a child element and specify the parent to select the correct element. The key identifiers in the parent element kept changing, so i was unable to select just that. I believe the XPATH is correct because when I put that into the website, it showed up as the correct line.
I have also tried using the code below, as i have seen some people suggest. When using that, I get a timed out error.
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//img[#src="//media.secondstreetapp.com/1973100?width=370&height=180&cropmode=Fill&anchor=Center"]/parent::div')))
Any help would be appreciated
NEW CODE for iFrames
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//iframe[#src="https://embed-882706.secondstreetapp.com/embed/ae709978-d6d1-499e-9f5e-136cc36eab1b/"]')))
mim = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//img[#src="//media.secondstreetapp.com/1973100?width=370&height=180&cropmode=Fill&anchor=Center"]/parent::div')))
mim.click
I am having issues clicking the item. To be fair, i am not sure that you are supposed to click that element to change the webpage. That is probably an issue.
Edit: nvm im just dumb that totally worked lol :))
You are getting "NoSuchElementException" error because the desired element is inside the iframe .So you have to switch to iframe at first.See the below image screenshot

Scroll down when the Scrollbar has no tag with Selenium for python

I wanted to scroll down in an element, where the scrollbar doesnt have a tag/element. I did quite a few research on this but i couldnt find anything for that specific case. Im using Selenium for Python
We are talking about the Site "www.swap.gg", its a site for csgo skins, and in order to load every item from the bot, you need to scroll down in the element "Bot inventory". The Site looks like this when using F12 in browser it looks like this The respective element
There is no key which you can use to scroll down there, therefore the .send_keys() command doesnt work by any chance. I also tried the touchactions.scroll_from_element(element,xoffset,yoffset) but didn't have any luck either. Im using Firefox as a webdriver incase that matters.
The xpath of the element is "/html/body/div/div1/section1/div[2]/div[3]/div[2]/div[2]"
The CSS selector is "div.is-paddingless:nth-child(3)"
Any ideas?
Find the parent div
element = driver.find_element_by_xpath('/html/body/div/div[1]/section[1]/div[2]/div[3]/div[2]/div[2]')
Scroll down to trigger the reload
driver.execute_script("arguments[0].scrollBy(0, 500)", element)
import selenium
import selenium.webdriver
import time
driver = selenium.webdriver.Chrome()
driver.get('https://swap.gg/')
element = driver.find_element_by_xpath('/html/body/div/div[1]/section[1]/div[2]/div[3]/div[2]/div[2]')
for i in range(20):
driver.execute_script("arguments[0].scrollBy(0, 500)", element)
time.sleep(2)

Python Selenium how to select a dropdown option in a google form

I'm having trouble to select the different options of this dropdown
in the field SIZE
https://docs.google.com/forms/d/e/1FAIpQLSdSpGLXjAV_wiI2qgg3B_KYxd4_7NR-DxHGrTySaIkAWIqmBg/viewform
Someone has a good solution?
Im able to click the element with
driver.find_element_by_xpath('/html/body/div/div[2]/form/div[2]/div/div[2]/div[14]/div/div/div[2]/div/div[1]/div[1]/div[1]').click()
But I'm not able to select the different options
You need to click the list to open it, then find and click the span with the right content inside it. Since there is a bit of drawing delay, you'll probably want it to use webdriverwait to ensure the element is ready before interacting.
This works for me:
driver = webdriver.Chrome()
driver.get("https://docs.google.com/forms/d/e/1FAIpQLSdSpGLXjAV_wiI2qgg3B_KYxd4_7NR-DxHGrTySaIkAWIqmBg/viewform")
#open the size menu
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[text()='SIZE']/following::div[#class='quantumWizMenuPaperselectOptionList'][1]"))).click()
#select the size by it's full text
sizeToSelect = "US 11"
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class,'exportSelectPopup')]/div/span[text()='"+sizeToSelect+"']"))).click()
If you've not already got them you need the following imports:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Highlight the word SIZE and right-click and click inspect. Now do it again and it will lead you to the HTML regarding that. Keep going down from the root of that very HTML till you find the part of the size you want(as you hover over the code, it will highlight the relevant part in the website). Hope this will help you enough to make the code function.

Automate Login with Selenium and Python

I am trying to use Selenium to log into a printer and conduct some tests. I really do not have much experience with this process and have found it somewhat confusing.
First, to get values that I may have wanted I opened the printers web page in Chrome and did a right click "view page source" - This turned out to be not helpful. From here I can only see a bunch of <script> tags that call some .js scripts. I am assuming this is a big part of my problem.
Next I selected the "inspect" option after right clicking. From here I can see the actual HTML that is loaded. I logged into the site and recorded the process in Chrome. With this I was able to identify the variables which contain the Username and Password. I went to this part of the HTML did a right click and copied the Xpath. I then tried to use the Selenium find_element_by_xpath but still no luck. I have tried all the other methods to (find by ID, and name) however it returns an error that the element is not found.
I feel like there is something fundamental here that I am not understanding. Does anyone have any experience with this???
Note: I am using Python 3.7 and Selenium, however I am not opposed to trying something other than Selenium if there is a more graceful way to accomplish this.
My code looks something like this:
EDIT
Here is my updated code - I can confirm this is not just a time/wait issue. I have managed to successfully grab the first two outer elements but the second I go deeper it errors out.
def sel_test():
chromeOptions = Options()
chromeOptions.add_experimental_option("useAutomationExtension", False)
browser = webdriver.Chrome(chrome_options=chromeOptions)
url = 'http://<ip address>/'
browser.get(url)
try:
element = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="ccrx-root"]')))
finally: browser.quit()
The element that I want is buried in this tag - Maybe this has something to do with it? Maybe related to this post
<frame name="wlmframe" src="../startwlm/Start_Wlm.htm?arg11=">
As mentioned in this post you can only work with the current frame which is seen. You need to tell selenium to switch frames in order to access child frames.
For example:
browser.switch_to.frame('wlmframe')
This will then load the nested content so you can access the children
Your issue is most likely do to either the element not loading on the page until after your bot searches for it, or a pop-up changing the xpath of the element.
Try this:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
delay = 3 # seconds
try:
elementUsername = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.xpath, 'element-xpath')))
element.send_keys('your username')
except TimeoutException:
print("Loading took too much time!")
you can find out more about this here

Categories

Resources