How to click css selector by text using selenium python - python

I would like to test some actions. In this case, I need to click on the text to get an upload form, but none of the forms below do not lead to the desired result.
This part of HTML-code, where I need to do some actions:
<a href="javascript:;" class="dg-hider st-mb__20 st_add-material__link" onclick="iu.ajax(event,'https://alexanderro.com/ajax/documentAddGsiUpload');">
Choose your category
</a>
<div id="GSIData"></div>
none of these works:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "dg-hider st-mb__20 st_add-material__link"))).click()
driver.find_element_by_class_name("dg-hider st-mb__20 st_add-material__link").click()
driver.find_element_by_id("GSIData").click()
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.ID, "GSIData"))).click()
driver.find_element_by_css_selector("a[onclick*=https://alexanderro.com/ajax/documentAddGsiUpload]").click()
Could you help me?

You need to wait for the element for its presence or visibility:
You can use the below code snippet, it should work
def wait_for_element_to_be_clickable(element):
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, element)))
element = "a.dg-hider.st-mb__20.st_add-material__link"
wait_for_element_to_be_clickable(element)
driver.find_element_by_css_selector(element).click()
print("Clicked")

I can't make a comment in Stack Overflow, so I'll try help you throug here:
Did you try:
driver.find_element_by_css_selector('[class="dg-hider st-mb__20 st_add-material__link"]').click()
or
driver.find_element_by_xpath('"//a[contains(text(), 'Choose your category')]"').click()

Related

Selenium Python finding elementS

I wrote a code that works perfectly in one website, but in another isn't working.
Basically the problem is finding elements.
Also, tried to find it by Relative XPATH and Absolute XPATH, and still it won't find it.
(On the problematic website)
I would like to minimilize sharing, if anything else would help tell me :)
working element:
<div id="areaAvail_0" class="areaAvail red button" style="top: 141.65px; left: 212.221px;" data-areaindex="0" data-areatype="ReservedSeating" data-areaid="f8c68849-c882-e911-80dd-984be16723b6" data-hasqtip="94">
</div>
problematic element:
<div id="areaAvail_0" class="areaAvail red button" style="top: 213.238px; left: 91.901px;" data-areaindex="0" data-areatype="GeneralAdmission" data-areaid="20d4c178-7539-ed11-83d1-e7ab999ef3a1" data-hasqtip="1" aria-describedby="qtip-1">
</div>
The code:
driver = webdriver.Chrome(service=serv_obj)
wait = WebDriverWait(driver, 300)
driver.get(url)
driver.maximize_window()
list1 = driver.find_elements(By.CSS_SELECTOR, "div.areaAvail[data-areaindex]")
wait.until((EC.element_to_be_clickable((By.CSS_SELECTOR, "div.areaAvail[data-areaindex]"))))
print(len(list1))
when i use the Element_to_be_clickable, it's just "stuck" in that line.
if i use time.sleep(), after the time passes it will print 0 (the problemtic website).
Any ideas or suggestions?
thanks in advance!
So the problem is solved.
It was indeed inside an iframe
in order to click the element inside the iframe, i used these lines:
wait.until((EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#myIframe"))))
wait.until((EC.element_to_be_clickable((By.CSS_SELECTOR, "div.areaAvail[data-areaindex]"))))
thanks everyone!

Selenium: Unable to locate element by class and id

Trying to scrape a website, I created a loop and was able to locate all the elements. My problem is, that the next button id changes on every page. So I can not use the id as a locator.
This is the next button on page 1:
<a rel="nofollow" id="f_c7" href="#" class="nextLink jasty-link"></a>
And this is the next button on page 2:
<a rel="nofollow" id="f_c9" href="#" class="nextLink jasty-link"></a>
Idea:
next_button = browser.find_elements_by_class_name("nextLink jasty-link")
next_button.click
I get this error message:
Message: no such element: Unable to locate element
The problem here might be that there are two next buttons on the page.
So I tried to create a list but the list is empty.
next_buttons = browser.find_elements_by_class_name("nextLink jasty-link")
print(next_buttons)
Any idea on how to solve my problem? Would really appreciate it.
This is the website:
https://fazarchiv.faz.net/faz-portal/faz-archiv?q=Kryptow%C3%A4hrungen&source=&max=10&sort=&offset=0&_ts=1657629187558#hitlist
There are two issues in my opinion:
Depending from where you try to access the site there is a cookie banner that will get the click, so you may have to accept it first:
browser.find_element_by_class_name('cb-enable').click()
To locate a single element, one of the both next buttons, it doeas not matter, use browser.find_element() instead of browser.find_elements().
Selecting your element by multiple class names use xpath:
next_button = browser.find_element(By.XPATH, '//a[contains(#class, "nextLink jasty-link")]')
or css selectors:
next_button = browser.find_element(By.CSS_SELECTOR, '.nextLink.jasty-link')
Note: To avoid DeprecationWarning: find_element_by_* commands are deprecated. Please use find_element() import in addition from selenium.webdriver.common.by import By
You can't get elements by multiple class names. So, you can use find_elements_by_css_selector instead.
next_buttons = browser.find_elements_by_css_selector(".nextLink.jasty-link")
print(next_buttons)
You can then loop through the list and click the buttons:
next_buttons = browser.find_elements_by_css_selector(".nextLink.jasty-link")
for button in next_buttons:
button.click()
Try below xPath
//a[contains(#class, 'step jasty-link')]/following-sibling::a

How to click a Vue/Vuetify card using selenium in python?

I am using selenium version 4.0.0, for reference.
I'm trying to click a Vuetify card element, which is acting as a button, but I running into an element not interactable: [object HTMLDivElement] has no size and location or just element not interactable errors. I have been able to solve similar problems with action chains in the past, but it doesn't seem to work with this.
This is the list element the button is contained within:
<li class="lu-li list-item" data-v-711d8d7a="" style="display: flex;">
<div class="addCard v-card v-card--link v-sheet theme--light" data-v-711d8d7a="" tabindex="0" onselectstart="return false;">
::before
<i class="v-icon notranslate btnAdd material-icons theme--light enableIcon" data-v-711d8d7a="" aria-hidden="true">
add
::after
</i>
</div>
</li>
The first things I tried was simply clicking on the element, and then clicking on the <i> element beneath it when that didn't work:
addQLButton = driver.find_element(By.CLASS_NAME, "addCard")
addQLButton.click()
addQLButton = driver.find_element(By.CLASS_NAME, "btnAdd")
addQLButton.click()
I have already tried using WebDriverWait on both the v-card <div> and <i> element to make sure they are available before being clicked, which it passes without any issues:
WebDriverWait(driver, timeout=10).until(lambda d: d.find_element(By.CLASS_NAME, "addCard"))
WebDriverWait(driver, timeout=10).until(lambda d: d.find_element(By.CLASS_NAME, "btnAdd"))
I have already tried using action chains to make sure the elements are visible (this has worked in the past with similar errors), but I still run into the same issue:
addQLButton = driver.find_element(By.CLASS_NAME, "addCard")
actions.move_to_element(addQLButton).perform()
driver.execute_script("arguments[0].click();", addQLButton)
addQLButton = driver.find_element(By.CLASS_NAME, "btnAdd")
actions.move_to_element(addQLButton).perform()
driver.execute_script("arguments[0].click();", addQLButton)
The elements are not in an iframe, and I am sure I have the correct window selected as I am still able to interact with its elements.
I am at a bit of a loss, any help would be much appreciated. I'm happy to answer any clarifying questions if I didn't explain the issue clearly enough.
I managed to get it working with some javascript:
js = "document.querySelector('.btnAdd').click();"
driver.execute_script(js)

Alternatives to using selenium XPATH to find an element?

On this website, I'm trying to find an element based on its XPATH, but the XPATH keeps changing. What's the next best alternative?
Snippet from website
<button class="KnkXXg vHcWfw T1alpA kiPMng AvEAGQ vM2UTA DM1_6g _-kwXsw Mqe1NA SDIrVw edrpZg" type="button" aria-expanded="true"><span class="nW7nAQ"><div class="VpIG5Q"></div></span></button>
XPATH:
//*[#id="__id15"]/div/div/div[1]/div[2]/div
#Sometimes id is a number between 15-18
//*[#id="__id23"]/div/div/div[1]/div[2]/div
#Sometimes id is a number between 13-23
Here's how I use the code:
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, """//*[#id="__id3"]/div/div/div[1]/div[2]/div/div/div/button"""))).click()
I've tried clicking the element by finding the button class, but for whatever reason it won't do anything.
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "KnkXXg vHcWfw T1alpA kiPMng AvEAGQ vM2UTA DM1_6g _-kwXsw Mqe1NA SDIrVw edrpZg"))).click()
If Part of the text is keep changing you can use contains in the xpath.
//*[contains(#id,"__id"]/div/div/div[1]/div[2]/div

Selenium click like on twitter

What is the most recent and up to date way to click "like" on a tweet using selenium?
From the css, it looks like I need to click on this:
<div aria-haspopup="false" aria-label="131310 Likes. Like" role="button" data-focusable="true" tabindex="0" class="css-18t94o4 css-1dbjc4n r-1777fci r-11cpok1 r-1ny4l3l r-bztko3 r-lrvibr" data-testid="like">
That is found on a profile page. My goal isn't to exactly like a tweet on a profile page but If I can figure this out, I'll be able to figure out what I actually want to do.
I have tried a bunch of ways but here are my most recent:
like_btn = (By.XPATH, ("//div[#data-testid='like', #class='css-18t94o4 css-1dbjc4n r-1777fci r-11cpok1 r-1ny4l3l r-bztko3 r-lrvibr']"))
like_btn = (By.XPATH, ("//div[#data-testid='like'"))
copy of Xpath:
like_btn = (By.XPATH, ("//*[#id='react-root']/div/div/div/main/div/div/div/div[1]/div/div[2]/div/div/div[2]/section/div/div/div/div[3]/div/article/div/div[2]/div[2]/div[4]/div[3]/div"))
Copy of full xpath:
like_btn = (By.XPATH, ("/html/body/div/div/div/div/main/div/div/div/div[1]/div/div[2]/div/div/div[2]/section/div/div/div/div[3]/div/article/div/div[2]/div[2]/div[4]/div[3]/div"))
The method then uses:
def like_user_tweets(self, user_tweets=UserStatuses.like_btn):
self.like_btn.click()
It looks like twitter recently revamped everything because even github code from only a year or less ago uses "HeartAnimation" class to find the like button but that doesn't seem to exist anymore.
The error: AttributeError: 'NoneType' object has no attribute 'click'
It is a button so shouldn't it be able to click?
How can I click the like/favorite button?
Error message:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted:
Element <div aria-label="394 Likes. Like" role="button" tabindex="0"
data-testid="like">...</div> is not clickable at point (539, 10).
Other element would receive the click: <div class="css-1dbjc4n r-1habvwh">...</div>
Solution:
browser = webdriver.Chrome()
infoq_url = 'https://twitter.com/infoqchina'
browser.get(infoq_url)
sleep(2)
like_buttons = browser.find_elements(By.XPATH, '//div[#data-testid="like"]')
like_btn = like_buttons[0]
like_svg = like_btn.find_element(By.TAG_NAME, "svg")
like_svg.click()
Reference:
btn_parent = btn.find_element(By.XPATH, "..") # find parent element.

Categories