Locate text which loads dynamically Python Selenium WebDriver - python

My problem is that I am trying to get the text of the element, which fills up with HTML content dynamically. Here is HTML source code. The last div:
<div data-bind="with: dataForRatingPopup"></div>
Fills with HTML code when the mouse enters the first div:
<div class="star-rating-wrap" data-bind="event: { mouseenter: mouseEnter, mouseleave: mouseLeave, click: click }, css: { 'has-supplier': emex.context.userIsInOptovikInterface }">
<div class="star-rating rating-6" data-bind="css: css"></div>
<div data-bind="with: dataForRatingPopup"></div>
</div>
How can I get the text of this element using Selenium WebDriver?

You can use webdriverwait function for this
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 100).until(
EC.text_to_be_present_in_element((By.XPATH, '//div[contains(#data-bind, "dataForRatingPopup")]'), "txt you want to match")
)
Above code will wait up to 100 seconds to find a div (whose #data-bind attribute contains the value "dataForRatingPopup") which contains the text "txt you want to match"
Useful links :
https://christopher.su/2015/selenium-chromedriver-ubuntu/ (You can skip pyvirtualdisplay usage in that)
http://selenium-python.readthedocs.io/getting-started.html#simple-usage

Related

How to click on checkbox filter with selenium Python?

I'm trying to click on a checkbox filter on a website with selenium python. This is a part of its HTML code linked to one of the checkbox options.
<div class="shopee-checkbox" bis_skin_checked="1">
<label class="shopee-checkbox__control">
<input type="checkbox" name="" value="Jabodetabek">
<div class="shopee-checkbox__box" bis_skin_checked="1">
<i> </i>
</div>
<span class="shopee-checkbox__label">Jabodetabek</span>
</label>
</div>
I tried following, but it didn't work.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://shopee.co.id/search?keyword=baju%20laki-laki')
time.sleep(5)
driver.find_element(By.XPATH, "//input[#value='JABODETABEK']").click()
I read the answers to similar questions, mostly they suggest using 'id' and 'name' to find the element. However, in this input tag, there are only 'type' and 'value'.
Here is one way to select that checkbox:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
[...]
wait = WebDriverWait(driver, 25)
[..]
wait.until(EC.element_to_be_clickable((By.XPATH, '//span[text()="Jabodetabek"]'))).click()
print('clicked on Jabodetabek')
Selenium documentation can be found here.
#value for the checkbox in the xpath is incorrect. The selenium web locator techniques are case sensitive. So make sure to use exact values while identifying objects. Changing your xpath to below would fix the issue.
driver.find_element(By.XPATH, "//input[#value='Jabodetabek']").click()

function click with selenium without id

I want know how I can click a button in this page here with selenium the code I try is this
import selenium
from selenium import webdriver
from time import sleep
PATH= "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://yopmail.com/it/")
inputsSI= driver.find_element_by_class_name("md").click()
print(inputsSI)
sleep(100)
driver.close()
the error I get is this:
Message: element not interactable
It's because find_element_* methods will return the first occurrence of the element they find. If you see the HTML page there is another div element before the button that has this "md" class and of course it is not the button you are looking for.
You are looking for this buttun :
<div id="refreshbut">
<button class="md" style="border-radius: 20px;"
title="Controllare la posta #yopmail.com"
onclick="{if(chkl())go()}"><i
class="material-icons-outlined f36"></i></button>
<input type="submit" style="display:none;">
</div>
It is wrapped inside a div with id of "refreshbut".
So all you have to do is first get this div by id. Then search for the element which has the "md" class which is indeed the button you are looking for. (you could also get the button with XPATH. it's up to you)
like:
inputsSI = driver.find_element(By.ID, "refreshbut") \
.find_element(By.CLASS_NAME, "md") \
.click()
Note 1: It's better to use raw-string for your PATH variable.
Note 2: I would put the driver.close() statement inside the finally block so that it always runs
To click on the md button use button.md as a selector then wait for the element to be interactable. I don't know what goes in there so I just added a send keys of a.
wait=WebDriverWait(driver,30)
driver.get("https://yopmail.com/it/")
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#login"))).send_keys('a')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button.md"))).click()
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Selenium function in Python to find on page and element that contains partial text

I am getting regurarly a lot of mails which contains some filenames and their IDs (e.g. FILENAME_VERSION_ID). Based on these IDs I have to log in on a portal and download every file separately. So I have made a script in Python based on Selenium to download these files automatically.
My program works the following way:
The script extracts the IDs of these file in a txt called ID.txt.
Then, I have used a for loop to read every line of the ID file till it ends.
So what I want now is to find the elements from ID.txt based on partial text in the full filename (the id of the filename).
with open('ID.txt') as f:
for line in f:
driver.find_element_by_xpath("//*[contains(#id,'%s')]" % str(line))
pyautogui.press('enter')
driver.find_element_by_xpath("//*[text()='ro']").click()
driver.find_element_by_xpath("//*[contains(#id,'%s')]" % str(line)).click()
driver.find_element_by_xpath("//*[text()='export']").click()
if 'str' in line:
break
Apparently selenium cannot find the element for this line of code
driver.find_element_by_xpath("//*[contains(#id,'%s')]" % str(line))
One element on the site I want to click looks the following way:
<div index="0" aria-busy="false" aria-checked="false" aria-disabled="false" data-head="true" aria-label="09251561001.09251561001.1.31873860875, folder" aria-selected="false" class="option grid-row" role="option" id=":DOMLT_ELISYS:export:09251561001.09251561001.1.31873860875">
<div class="name-data icon folder" id="id1027">
<div class="progressbar" role="progressbar" aria-hidden="true" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<div class="fill" role="presentation" style="width: 0%;"></div>
<div class="fill" role="presentation" style="width: 0%;"></div>
</div>
<a class="name-text" href="#">
<span>09251561001.09251561001.1.31873860875</span>
</a>
</div>
<div id="cellId1028" class="date-data"></div>
<div id="cellId1029" class="size-data"></div>
</div>
In my ID.txtfile are stored only the last numbers after dot (31873860875, in this specific case).
I have tried a lot of possibilities but it is not working. I get the following error:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[contains(#id,'31873860875
')]"}
What am I not doing right here? It is there an alternative way to select/click this element on the site?
This happens a lot of time when the element is not loaded and you are trying to locate it. You can use waits to resolve this issue so that proper loading of DOM takes place .
https://selenium-python.readthedocs.io/waits.html
One of the following will be useful
presence_of_element_located
visibility_of_element_located
presence_of_all_elements_located
element_to_be_clickable
WebDriverWait should help you in this case:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
# from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.ui import WebDriverWait
botton_to_click = WebDriverWait(driver, 10).until(EC.element_to_be_clickable, ((By.XPATH,"//*[text()='ro']")))
botton_to_click.click()
I believe after the program waitsenough for clicking text()='ro', it will be able to click "//*[contains(#id,'%s')]". If not, you can do the same botton_to_click thing for the following XPaths.
driver.find_element_by_xpath("//*[contains(#id,'%s')]" % str(line)).click()
driver.find_element_by_xpath("//*[text()='export']").click()
You were close enough. The text 31873860875 is with in a <span> tag and is the text.
So to locate the element you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, ""//a[#class='name-text']/span[contains(.,'%s')]" % str(line)))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

Getting "element not visible" using selenium python for SAP EPM browser application

I am trying to automate an SAP EPM Application using Selenium Python. It's a browser based application. I am able to open the home page, after that I have to click on one tile. But I was unable to click it. It says "element not visible".
I tried using xpath, id but no luck.
Tile HTML:
<div class="tile tile-webdyn draggable tileBGColor ui-draggable ui-draggable-handle
ui-droppable border-norm" id="PLANCHGWO" style="position: relative;">
<div class="tileName">
<center>Change PM Order</center>
</div>
<div class="tileImage">
<center>
<img width="50px" height="50px" src="EDWO.png">
</center>
</div>
</div>
You could try invoking a wait, then click the desired WebElement with Javascript to work around the not visible error you are seeing.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
# wait for element to exist, then store it in tile variable
tile = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//center[text()='Change PM Order']")))
# click the element with Javascript
driver.execute_script("arguments[0].click();", tile)
If this does not work, we will probably need to see the full page HTML to understand the element you are trying to click. It's possible it is hidden in an iframe or obscured by other elements on the page.

Python Selenium select div class with blanks

I've got a problem while trying to select a div tag class that has some white spaces in it.
This is the structure of page:
<div class="sadasd-dashboardtab even asdasd-syndicating_from_my_file" id="124121_1540012412412414">
<div id="124121_154006585856856858">
<span class="label">Syndicating From My File</span>
<button class="column-dropdown" title="Click for more tab options"></button>
</div>
</div>
This are my tries of code for this part:
#syndicating_button = driver.find_element_by_xpath("//span[text()='Syndicating From My File']")
#syndicating_button = driver.find_element_by_xpath("//div[#class='yui3-dashboardtab even s-tab-syndicating_from_my_site']")
syndicating_button = driver.find_element_by_css_selector("div.yui3-dashboardtab.even.s-tab-syndicating_from_my_site")
syndicating_button.click()
Your issue has nothing to do with "blanks"/"whitespaces" as your selectors should work well... if element is present in DOM. Try to wait until element appears in DOM and becomes clickable:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.support import expected_conditions as EC
wait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Syndicating From My Site']"))).click()

Categories