How to select dropdown in the dynamic table Selenium webdriver - python

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')

Related

How to get data of html table with selenium python

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

How to locate element without id,name and xpath in webdriver selenium google chrome

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

how to select date in jquery date time picker in selenium python

I want to select the date and time from jquery date time picker which is present inside the iframe. I have switched to frame and clicked on the field which opens the date time picker but i want to send value from my code like send keys,but I'm not able to send. I'm doing this in python.
Here is my html code:
<div class="add_folder">
<form method="POST" action="some action url " id="add-attendance">
<table class="table_blue" >
<tr>
<td> <label for="start_time">Start Time</label></td>
<td><input type="text" value="" name="start_time" id="start_time"/></td>
</tr>
<tr>
<td> <label for="end_time">End Time</label></td>
<td> <input type="text" value="" name="end_time" id="end_time"/> </td>
</tr>
<tr>
I did this using xpath but it didn't worked for me. Here is my selenium code to send keys:
driver.find_element_by_xpath('[#id="unowacalendar"]/div/div/table/tbody/tr[2]/td[5]').send_keys("2019-12-03")
Try targeting the input elements. For example:
driver.find_element_by_id('start_time').send_keys('yourValue')
You may need a wait e.g.
WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.ID , 'start_time'))).send_keys('yourValue')
Additional imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

Python selenium checkbox click does not work

Hey im using python selenium to download data from table. But when im want to prepare data i cant select a checkbox 'toggle all'....
im geting on page:
browser.get("https://gold.jgi.doe.gov/studies?setColumns=yes&Organism.NCBI+Taxonomy+ID=%3D500633")
click 'select columns for table'
browser.find_element_by_xpath('//*[#id="showColsButton"]').click()
and here we are checkbox ;toggle all'...
browser.find_element_by_xpath('//*[#id="selectFieldsList"]/thead/tr[2]/td/input').click()
Realy tryed xpath, css selector....
and here we are html fragment:
<table class="selectFieldsList" id="selectFieldsList">
<thead>
<tr><td colspan="2" align="center">
Select Fields using the Checkboxes<br>
<input type="submit" value="Submit" name="fieldSubmit" id="submitMe" class="submitMe">
</td></tr>
<!-- add a select all option -->
<script language="JavaScript">
function toggle(source) {
checkboxes = document.getElementsByName('selectField');
for(var i=0, n=checkboxes.length;i<n;i++) {
checkboxes[i].checked = source.checked;
}
}
</script>
<tr><td> <input type="checkbox" onclick="toggle(this)"> Toggle All<br> </td></tr>
<tr><td>* = required column</td><td> </td> </tr>
<tr><td> <input type="button" id="entityFieldSelectorToggle" value="Expand All Fields"> </td>
</tr></thead>
<tbody>
Instead of using sleep use explicit wait is good practise, because it will same 5 sec of time even after element is found. Hope it will be useful to you
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver.get("https://gold.jgi.doe.gov/studies?setColumns=yes&Organism.NCBI+Taxonomy+ID=%3D500633")
driver.find_element_by_xpath('//*[#id="showColsButton"]').click()
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="selectFieldsList"]/thead/tr[2]/td/input')))
driver.find_element_by_xpath('//*[#id="selectFieldsList"]/thead/tr[2]/td/input').click()

Selenium Source Missing Login Fields

I'm trying to use Selenium with Python to log into an ESPN page:
http://games.espn.go.com/ffl/scoreboard?leagueId=34467&matchupPeriodId=1
When you go to this page it pops up a login box but Selenium can't seem to find the fields for it.
Here's my code:
driver = webdriver.Chrome()
driver.get('http://games.espn.go.com/ffl/scoreboard leagueId=34467&matchupPeriodId=1')
username = driver.find_element_by_name('username')
username.send_keys('XXXXX')
password = driver.find_element_by_name('password')
password.send_keys('XXXXX')
submit_button = driver.find_element_by_name('submit')
submit_button.click()
When I view the page source in Chrome myself I see the form:
<table width=100% border=0 cellpadding=0 cellspacing=0 class="bodyCopy"><tr>
<td width=15%><b>MEMBER NAME:</b></td>
<td width=1%> </td>
<td><input name="username" size="16" maxlength="64" value="" class="select"> </td>
</tr>
<tr>
<td><b>PASSWORD:</b></td>
<td> </td>
<td><input type="password" name="password" size="16" maxlength="25" value="" class="select"></td>
</tr>
<tr>
<td colspan=2> </td>
<td><input type="submit" name="submit" value="Log In" class="select"></td>
</tr>
</form>
</table>
However, when I use...
page = driver.page_source
...the form is missing entirely. I can see the same form in the browser window that Selenium opens up though, it's just missing from the source. Any ideas?
The first problem is that the login form is inside an iframe and you need to switch to it:
driver.switch_to.frame("disneyid-iframe")
And, the second issue is that the form is loaded dynamically. You need to explicitly wait for the username field to show up before starting to log in (well, as a human would do):
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.visibility_of_element_located((By.CSS_SELECTOR, "div.field-username-email input")))
print(driver.page_source)
Note that your locators point to non-existing elements. Use instead:
username = driver.find_element_by_css_selector("div.field-username-email input")
password = driver.find_element_by_css_selector("div.field-password input")
submit_button = driver.find_element_by_xpath("//button[contains(., 'Log In')]")

Categories