I want to get some td data from dynamic table with selenium and push them in array.
I tried to use:
driver.find_elements_by_class_name("row_data")
and get the html then find td but the list element can't get attribute innerHTML ...
<tr class="row_data text-silver">
<td class="link">
<a href="/Account/UserCompleteRegister" data-toggle="tooltip" data-placement="left" title="ویرایش" class="btn btn-info btn-xs btnEditUser">
<i class="fa fa-edit"></i>
</a>
مرضیه<input type="hidden" value="1332162477" class="userId">
</td>
<td class="text-right">
ایرج ساعی
</td>
<td class="text-right">
6180033005
</td>
<td class="text-right">
</td>
<td class="text-right">
25 سال و 2 روز
</td>
<td class="text-right">
<span class="GenderText">زن</span>
</td>
</tr>
A bit of more information with respect to which data you are exactly looking for would have helped us to construct the answer in a canonical way. However as the class attribute of the <tr> node contains row_data and text-silver you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "tr.row_data.text-silver))).text)
Using XPATH:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//tr[#class='row_data text-silver']"))).text)
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
If its single table on your page and you want to use xpath then please refer below solution :
1. //table//td[*]
2. //table//tr//td[*]
or else provide specific table id to handle your tabel
Related
I have HTML tables like
<table id='table1'>
<tbody>
<tr>
<td colspan='2'>Food</td>
</tr>
<tr>
<td>Burger</td>
<td>
<select class="form-control input-sm" id="xx2" onchange="count(this)">
<option value="1">Burger</option>
<option value="2">spaghetti</option>
<option value="3">Kebab</option>
</select>
</td>
</tr>
<tr>
<td colspan='2'>Drink</td>
</tr>
<tr>
<td>Burger</td>
<td>
<select class="form-control input-sm" id="kj2" onchange="count(this)">
<option value="1">Coffe</option>
<option value="2">Tea</option>
<option value="3">Milk</option>
</select>
</td>
</tr>
<tr>
<td colspan='2'> ... </td>
</tr>
<tr>
<td> .......... </td>
<td>
<select class="form-control input-sm" id="jj" onchange="count(this)">
<option value="1"> ... </option>
<option value="2"> ..... </option>
<option value="3"> .... </option>
</select>
</td>
</tr>
</tbody>
In selenium web driver, how to select first value at dropdownlist in the dynamic table (total rows is varry and there is colspan)
I have get table, and I want to get all and fill dropdownlist in the table
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="table1"]/tbody')))
table = driver.find_element(By.XPATH, '//*[#id="table1"]/tbody')
to get all vary data
from bs4 import BeautifulSoup
import requests
main_site = requests.get("http://yourhtmlfile.html")
soup = BeautifulSoup(main_site.content, 'html.parser')
table = soup.find(attrs={'id':'table1'})
select = table.find(attrs={'id':'xx2'})
res = []
for option in select.find_all('option'):
res.append(option["value"])
all option data is stored into res list
selectedDropDownList = Select(driver.find_element(By.ID, "xx2"))
selectedDropDownList.select_by_visible_text(res[0])
so, you can repeat this method to fullfill all dropdownlist
You can use the below XPath:
To select the first dropdown:
dropdown_1 = Select(driver.find_element(By.XPATH, "(.//*[#id='table1']//select[#class='form-control input-sm'])[1]"))
To select the second or third dropdown you can change the index in the XPath:
(.//*[#id='table1']//select[#class='form-control input-sm'])[2]
or
(.//*[#id='table1']//select[#class='form-control input-sm'])[3]
To select the first option from the dropdown:
dropdown_1.select_by_value(1)
or
dropdown_1.select_by_index(0)
Based on your html structure, you can use item reference like food or drink and then target following select element.
Use following xpath to identify each dropdown element.
dropdwon 1: "//td[text()='Food']/following::select[1]"
dropdwon 2: "//td[text()='Drink']/following::select[1]"
Use selenium select class to select the drop down values.
To handle dynamic element use WebDriverWait() and want for element clickable.
selectFood=Select(WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//td[text()='Food']/following::select[1]"))))
selectFood.select_by_value(1)
selectDrink=Select(WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//td[text()='Drink']/following::select[1]"))))
selectDrink.select_by_value(1)
You need to import following libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.select import Select
There are total three (3) html-select elements within the HTML provided and to select an option you have to use the Select() class and inducing WebDriverWait for the element_to_be_clickable() you can use either of the following locator strategies:
# using select_by_visible_text() to select spaghetti
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='xx2']")))).select_by_visible_text("spaghetti")
# using select_by_index() to select Tea
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='kj2']")))).select_by_index(2)
# using select_by_value() to select the second option from the third dropdown
Select(WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[#id='jj']")))).select_by_value('2')
I want to click a button Customer Details, but i got an error. This is an error from python :
Message: no such element: Unable to locate element
I tried a few code(listed below) but they didn't work. Any ideas?
1. driver.find_element_by_xpath("(//a[contains(text(),'Customer Details')])[11]").click()
2. driver.find_element_by_xpath("(//a[#href='https://mylink' and #class=' class="btn-sm bg-navy btn-default"']").click()
3. driver.find_element_by_link_text("Customer Details").click()
An this is my HTML Code:
<table class="table table-bordered table-striped dataTable no-footer DTFC_Cloned" style="width: 100%; padding: 0px; margin: 0px;" role="grid" aria-describedby="tbl_so_info">
<thead>
<tr role="row" style="height: 0px;">
<th class="sorting" tabindex="0" aria-controls="tbl_so" rowspan="1" colspan="1" aria-label=": activate to sort column ascending"></th>
<th class="sorting_desc" tabindex="0" aria-controls="tbl_so" rowspan="1" colspan="1" aria-label="Customer No.: activate to sort column ascending" aria-sort="descending"></th>
</tr>
</thead>
<tbody>
<tr role="row" class="odd" data-dt-row="0" style="height: 38px;">
<td data-dt-row="0" data-dt-column="0">
Customer Details
Create Ticket
</td>
</tr>
</tbody>
</table>
Using WebDriverWait wait for element to be clickable before click on it:
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, 10)
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, 'Customer Details'))).click()
# css selector
# wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'a[href="https://mylink"]'))).click()
To click() on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "Customer Details"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn-sm.bg-navy.btn-default[href='https://mylink']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn-sm bg-navy btn-default' and #href='https://mylink'][contains(.,'Customer Details')]"))).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
Reference
You can find a relevant detailed discussion in:
Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome
The xpath written by you was correct until u added [11].
Now your code is searching the a tag with Customer Details. But adding [11] will lead it to searching such element for 11th result which is not present in your code.
Hence its says no such element found.
Try writing only the below code and it would work fine.
xpath = " //a[contains(text(),'Customer Details')] "
NOTE:- NEVER USE these ([1] [11] [2]) things in your locators it is not a good approach as if the structure of the program changes then the locator might not work.
how can i locate element td without name , id attributes?
<tr class="odd" onmouseover="this.className='highlight'" onmouseout="this.className='odd'">
<td style="width:4%;">J199</td>
<td style="width:5%;">056962840</td>
<td style="width:3%;">S</td>
<td style="width:5%;">11</td>
<td style="width:7%;">0606353</td>
<td style="width:7%;">4846962</td>
<td style="width:3%;">1</td>
<td style="width:20%;">S1-4100181163-MANUAL</td>
<td style="width:5%;">2019-07-03</td>
<td style="width:5%;"> </td>
<td style="width:5%;cursor: pointer;"><span title="CSARL-SB/SINGAPORE PARTS DC">Y850</span></td>
<td style="width:5%;">2019-09-04</td>
<td> </td>
</tr>
i only want to locate
<td style="width:5%;">2019-09-04</td>
and call it in python webdriver
To locate the <td> with text as 2019-09-04 you have to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using xpath and element position:
element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "//tr[#class='odd' and contains(#onmouseover, 'highlight')]//following-sibling::td[12]")))
Using xpath and title CSARL-SB/SINGAPORE PARTS DC:
element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//span[contains(#title, 'CSARL-SB/SINGAPORE PARTS DC')]//following::td[1]")))
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
If you want to match <td> tag having the text of 2019-09-04 it would be something like:
//td[text()='2019-09-04']
If you want to match the <td> tag which is before the last <td> tag go for position() and last() functions combination:
//td[position()=last()-1]
More information: XPath Operators & Functions
I've been trying to select one image tag, however, since it doesn't have any name and id I'm having trouble while doing the same.
HTML:
<tr __gwt_row="0" __gwt_subrow="0" class="GPBYFDECG">
<td class="GPBYFDEBG GPBYFDEDG GPBYFDEEG datagridCellStyle">
<div style="outline-style:none;" __gwt_cell="cell-gwt-uid-29">
ACD DETAILS NEW
</div>
</td>
<td class="GPBYFDEBG GPBYFDEDG datagridCellStyle">
<div style="outline-style:none;" __gwt_cell="cell-gwt-uid-30">
ACD Details
</div>
</td>
<td class="GPBYFDEBG GPBYFDEDG GPBYFDEOG datagridCellStyle">
<div style="outline-style:none;" __gwt_cell="cell-gwt-uid-31" tabindex="0">
//IMAGE THAT I NEED TO SELECT AND CLICK
<img onload="this.__gwtLastUnhandledEvent="load";" src="http://172.00.00.00:8080/demoreports/DemoReportsApp/clear.cache.gif" style="width:25px;height:23px;background:url(http://172.00.00.00:8080/demoreport/DemoReportsApp/0210CFCB6CBE82D7E9FAC82D9F901495.cache.png) no-repeat -333px 0px;" border="0">
</div>
</td>
Code:
driver.find_element_by_xpath('//img[#onload="this.__gwtLastUnhandledEvent="load";"]').click()
Above code doesn't work.
Is there any other way, I can click() on this img as it generates javscript rendered reports.
The desired element is a dynamic element so you have to induce WebDriverWait for the desired ElementToBeClickable and you can use either of the following Locator Strategies as solutions:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "td.datagridCellStyle img[onload*='gwtLastUnhandledEvent'][src*='demoreports/DemoReportsApp/clear']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//td[contains(#class, 'datagridCellStyle')]//img[contains(#onload, 'gwtLastUnhandledEvent') and contains(#src, 'demoreports/DemoReportsApp/clear')]"))).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
<table _ngcontent-c19="" class="table">
<tbody _ngcontent-c19="">
<tr _ngcontent-c19=""><!---->
<td _ngcontent-c19="" class="ng-star-inserted">
<div _ngcontent-c19="" class="span3" style="height: auto;">
<div _ngcontent-c19="" class="text-center" style="visibility: visible;">
<button _ngcontent-c19="" class="b1" type="submit">Click This</button>
</div><!---->
</div>
</td>
</tr>
</tbody>
</table>
I'm trying to click a button inside a table using SELENIUM.
The Code I've Written is
driver.find_element_by_xpath("//*[contains(getText(),'Click This')]").click()
and
driver.find_element_by_class_name('b1').click()
they both throw an Element not Found Exception
you can try with this xpath :
wait = WebDriverWait(driver,30)
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(text(),'Click This') and #class='b1']"))).click()
Note that you will have to import :
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Because your code runs faster than your browser that's why you need to tell him to wait until the element is visible and clickable.
button = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.XPATH, "//button[text()='Click This']"))
button.click()