My code:
from selenium import webdriver
driver.get('http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia')
element = driver.find_element_by_id("Tabella")
time.sleep(5)
element.click()
time.sleep(5)
a=driver.find_element_by_id('rId_48').get_attribute('innerHTML')
print(a)
My output:
<td role="gridcell" style="" title="" aria-describedby="list_"><a title="Vedi su Google Maps" href="javascript:StatPortalOpenData.ODataUtility.openInStreetView(45.0760003999999,7.5911782);"><img alt="Vedi su Google Maps" height="25" width="25" style="vertical-align:middle" src="/sites/all/modules/spodata/metadata/viewer/multidimensional_viewer/img/streetView.png"></a></td>
<td role="gridcell" style="" class="" title="COLLEGNO" aria-describedby="list_Cccomune_608711150">COLLEGNO</td>
My desired output:
<td role="gridcell" style="" class="" title="COLLEGNO" aria-describedby="list_Cccomune_608711150">COLLEGNO</td><td role="gridcell" style="" class="" title="CITTA' METROPOLITANA DI TORINO" aria-describedby="list_Ccprovincia_1472723626">CITTA' METROPOLITANA DI TORINO</td>
So it is the second block of <td> </td>
Thank you!
If you want to target specific row and cell value you can use following CSS selector.
To print the element:
print(driver.find_element_by_css_selector("#rId_48>td:nth-child(2)").get_attribute('outerHTML'))
print(driver.find_element_by_css_selector("#rId_48>td:nth-child(3)").get_attribute('outerHTML'))
OR to print the text of the element
print(driver.find_element_by_css_selector("#rId_48>td:nth-child(2)").text)
print(driver.find_element_by_css_selector("#rId_48>td:nth-child(3)").text)
It looks like you selected the parent element of the <td> you want. Just use a css selector to get all the td elements inside it:
a=driver.find_elements_by_css_selector('#rId_48 td')
Note the "s" in find_elements.... This returns a list of all the <td> elements. So the one you want should be a[1].
Related
I'm trying to automate downloading a report, but my script is refusing to find the element to click on...
def wait_click(browser, by_what, where):
wait = WebDriverWait(browser, 20)
wait.until(EC.element_to_be_clickable((by_what, where))).click()
tillf_export = '//*[#id="panel__6940363340341543984_linkb_6940363340341543984"]'
# inside class
def download_tillf(self):
self.browser.get(system_export)
wait_click(self.browser, By.XPATH, tillf_export)
I've tried every possible way, switching away from XPATH, using parent elements and even execute_script with the js.
This is the div:
<table class="dxrpControl" cellspacing="0" cellpadding="0" id="panel__6940363340341543984" border="0" style="border-collapse:collapse;border-collapse:separate;">
<tbody><tr>
<td id="panel__6940363340341543984_HC" class="dxrpHeader dxrp-headerClickable dx-borderBox" style="text-align: center; border-bottom: 1.33333px solid rgb(198, 198, 198); border-bottom-left-radius: 0px; border-bottom-right-radius: 0px;"><div id="panel__6940363340341543984_CB" class="dxrpCollapseButton" style="margin-top: 1px;">
<img id="panel__6940363340341543984_CBImg" class="dxWeb_rpCollapseButton" src="/test/jlltp02/sjalvservicerdr/DXR.axd?r=1_89-UNelo" alt="Collapse/Expand">
</div><div class="dxrpHCW" style="padding-right: 19px;">
** <span id="panel__6940363340341543984_RPHT" class="dxrpHT dx-vam">Tillfällig export</span>
</div></td>
</tr><tr class="dxrpCR">
<td id="panel__6940363340341543984_RPC" class="dxrp dxrpcontent dx-borderBox"><div class="dxrpAW" style="">
<div id="panel__6940363340341543984_CRC" class="dx-borderBox dxrpCW">
<table border="0">
<tbody><tr>
<td><span class="UTDATANODTITLEDESC">Tillfällig export kan användas för att snabbt ta ned svaret på en fråga genom att bara ändra den i "Automatiska frågor". Detta för att slippa gå in i Citrix och spara ned filen på M:.</span></td>
</tr><tr>
<td valign="top"><a id="panel__6940363340341543984_linkb_6940363340341543984" class="UTDATANODLINK" href="javascript:outputClick('6940363340341543984');">>> Tillfällig export</a></td>
</tr>
</tbody></table>
</div>
</div></td>
</tr>
</tbody></table>
Can anyone see what I'm doing wrong? Would be forever grateful!
The id attribute of the desired element looks dynamic and the element itself is possibly a dynamic element so to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using PARTIAL_LINK_TEXT:
Tillfällig export
Using CSS_SELECTOR:
a.UTDATANODLINK[id*='linkb']
Using XPATH:
//a[#class='UTDATANODLINK' and contains(., 'Tillfällig export')]
I am trying to scrape the data in a bunch of rows. I am able to expand an individual row using the following:
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="7858101"]'))).click()
The problem is each row has a different id. They have common class name so I have also tried:
WebDriverWait(driver, 60).until(EC.presence_of_elements_located((By.CLASS_NAME, 'course-row normal faculty-BU active'))).click()
I have attached a few rows below Any suggestions on how I can fix this
<tr id="7858101" class="course-row normal faculty-BU active" data-cid="7858101" data-cc="ACTG1P01" data-year="2021" data-session="FW" data-type="UG" data-subtype="UG" data-level="Year1" data-fn2_notes="BB" data-duration="2" data-class_type="ASY" data-course_section="1" data-days=" " data-class_time="" data-room1="ASYNC" data-room2="" data-location="ASYNC" data-location_desc="" data-instructor="Zhang, Xia (Celine)" data-msg="0" data-main_flag="1" data-secondary_type="E" data-startdate="1631073600" data-enddate="1638853200" data-faculty_code="BU" data-faculty_desc="Goodman School of Business">
<td class="arrow"><span class="fa fa-angle-down"></span></td>
<td class="course-code">ACTG 1P01 </td>
<td class="title">Introduction to Financial Accounting <div class="details-loader" style="display: none;"><span class="fa fa-refresh fa-spin fa-fw"></span></div></td>
<td class="duration">D2</td>
<td class="days"> </td>
<td class="time"> </td>
<!-- <td class="start" data-sort-value="1631073600">Sep 08, 2021</td> -->
<!-- <td class="end" data-sort-value="1638853200">Dec 07, 2021</td> -->
<td class="type">ASY</td>
<td class="data"><div style="" class="course-details-data">
<div class="description">
<h3>Introduction to Financial Accounting</h3>
<p class="page-intro">Fundamental concepts of financial accounting as related to the balance sheet, income statement and statement of cash flows. Understanding the accounting cycle and routine transactions. Integrates both theoretical and practical application of accounting concepts.</p>
<p><strong>Format:</strong> Lectures, discussion, 3 hours per week.</p>
<p><strong>Restrictions:</strong> open to BAcc majors.</p>
<p><strong>Exclusions:</strong> Completion of this course will replace previous assigned grade and credit obtained in ACTG 1P11, 1P91 and 2P51.</p>
<p><strong>Notes:</strong> Open to Bachelor of Accounting majors. </p>
</div>
<div class="vitals">
<ul>
<li><strong>Duration:</strong> Sep 08, 2021 to Dec 07, 2021</li>
<li>
<strong>Location:</strong> ASYNC </li>
<li><strong>Instructor:</strong> Zhang, Xia (Celine)</li>
<li><strong>Section:</strong> 1</li>
</ul>
</div>
<hr>
</div>
</td>
</tr>
<tr id="3724102" class="course-row normal faculty-BU active" data-cid="3724102" data-cc="ACTG1P01" data-year="2021" data-session="FW" data-type="UG" data-subtype="UG" data-level="Year1" data-fn2_notes="BB" data-duration="2" data-class_type="LEC" data-course_section="2" data-days=" M R " data-class_time="1100-1230" data-room1="GSB306" data-room2="" data-location="GSB306" data-location_desc="" data-instructor="Zhang, Xia (Celine)" data-msg="0" data-main_flag="1" data-secondary_type="E" data-startdate="1631073600" data-enddate="1638853200" data-faculty_code="BU" data-faculty_desc="Goodman School of Business">
<td class="arrow"><span class="fa fa-angle-right"></span></td>
<td class="course-code">ACTG 1P01 </td>
<td class="title">Introduction to Financial Accounting <div class="details-loader"><span class="fa fa-refresh fa-spin fa-fw"></span></div></td>
<td class="duration">D2</td>
<td class="days">
<table class="coursecal">
<thead>
<tr>
<th class="">S</th>
<th class="active">M</th>
<th class="">T</th>
<th class="">W</th>
<th class="active">T</th>
<th class="">F</th>
<th class="">S</th>
</tr>
</thead>
<tbody>
<tr>
<td class="weekend "></td>
<td class="active"></td>
<td class=""></td>
<td class=""></td>
<td class="active"></td>
<td class=""></td>
<td class="weekend "></td>
</tr>
</tbody>
</table>
</td>
<td class="time">1100-1230</td>
<!-- <td class="start" data-sort-value="1631073600">Sep 08, 2021</td> -->
<!-- <td class="end" data-sort-value="1638853200">Dec 07, 2021</td> -->
<td class="type">LEC</td>
<td class="data"></td>
</tr>
Are almost there...
You can retrieve a list of all the relevant web elements with the use of driver.find_elements method and then to iterate over each element in the list clicking on it.
Since course-row normal faculty-BU active is actually several class names, not a single class name, you should use XPath or CSS Selector there.
Also it's recommended to use visibility_of_element_located expected condition here, not presence_of_elements_located since the former condition is fulfilled even when the web element is not finally rendered on the page while visibility_of_element_located expected condition waits for more mature state of the web element
WebDriverWait(driver, 60).until(EC.visibility_of_element_located((By.XPATH, '//tr[#class = "course-row normal faculty-BU active"]')))
time.sleep(0.4) #short delay added to make ALL the elements loaded
elements = driver.find_element(By.XPATH, '//tr[#class = "course-row normal faculty-BU active"]')
for element in elements:
element.click()
#scrape the data you need here etc
As the id attributes of the <tr> have dynamic value to identify all the <tr>s and click on each of them you need to induce WebDriverWait for the visibility_of_all_elements_located() and you need to construct a dynamic locator strategy as follows:
Using CSS_SELECTOR:
elements = WebDriverWait(driver, 60).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "tr.course-row.normal.faculty-BU.active[data-faculty_desc='Goodman School of Business'] a[data-cc][data-cid]")))
for element in elements:
element.click()
Using XPATH:
elements = WebDriverWait(driver, 60).until(EC.visibility_of_all_elements_located((By.XPATH, "//tr[#class='course-row normal faculty-BU active' and #data-faculty_desc='Goodman School of Business']//a[#data-cc and #data-cid]")))
for element in elements:
element.click()
I was trying to extract the data from the website, here:
https://apps.ecology.wa.gov/tcpwebreporting/reports/ust?CityZip=Seattle&County=King&StoredSubstance=Unleaded%20Gasoline
I click the > button to get more details of each gas station. I was trying to scrape the data, but I couldn't find a way to click > button using my codes.
I am able to extract each row's elements. what should I do next?
driver = webdriver.Chrome(executable_path=r'C:\Users\Owner\Desktop\Career\Coltura\chromedriver.exe')
driver.get('https://apps.ecology.wa.gov/tcpwebreporting/reports/ust?CityZip=Seattle&County=King&StoredSubstance=Unleaded%20Gasoline')
buttons = driver.find_elements_by_class_name(' details-control parent-td clickable parent-control')
driver.find_elements_by_tag_name('tr')
<tr class="clickable odd details" role="row">
<td class=" details-control parent-td clickable parent-control">
<button title="Toggle more information about the site RICK'S CHEVRON GROCERY" class="btn btn-sm btn-whitesmoke"></button>
</td>
<td class=" parent-td">27</td>
<td class=" parent-td">41179492</td>
<td class=" parent-td">A3602</td>
<td class=" parent-td">RICK'S CHEVRON GROCERY</td>
<td class=" parent-td">8506 5TH AVE NE</td>
<td class=" parent-td">Seattle</td>
<td class=" parent-td">98115</td>
<td class=" parent-td">King</td>
<td class=" parent-td">Northwest</td>
</tr>
To locate element with multiple class name, you can use *_by_css_selector not _by_class_name.
I suggest to use method : .location_once_scrolled_into_view before click the element.
This is for click each arrow button you mean:
driver.get('https://apps.ecology.wa.gov/tcpwebreporting/reports/ust?CityZip=Seattle&County=King&StoredSubstance=Unleaded%20Gasoline')
#add some wait here.....
arrows = driver.find_elements_by_css_selector('td[class*="details-control"]')
for arrow in arrows:
arrow.location_once_scrolled_into_view
time.sleep(0.5)
arrow.click()
I'm using Ghost for Python 2.7 and I'm trying to click in a link which is in a table. The problem is that I have no ID, name... This is the HTML code:
<table id="table_webbookmarkline_2" cellpadding="4" cellspacing="0" border="0" width="100%">
<tr valign="top">
<td>
<a href="/dana/home/launch.cgi?url=.ahuvs%3A%2F%2Fhq0l5458452ERA-w-Xz8G3LKe8JNM%2F.ISDXWXaWXUivecOc" target="_blank" onClick='javascript:openBookmark(
this.href, "yes", "yes");
return false;' ><img src="/dana-cached/imgs/icn18x18WebBookmarkPop.gif" alt="This will open in a new TAB" width="18" height="18" border="0" ></a>
</td>
<td width="100%" align="left">
<a href="/dana/home/launch.cgi?url=.ahuvs%3A%2F%2Fhq0l5458452ERA-w-Xz8G3LKe8JNM%2F.ISDXWXaWXUivecOc" target="_blank" onClick='JavaScript:openBookmark(
this.href, "yes", "yes");
return false;' ><b>**LINK WHERE I WANT TO CLICK**</b> </a><br><span class="cssSmall"></span>
</td>
</tr>
</table>
How can I click in this kind of link ?
Seems like Ghost's Session.click() takes a CSS selector. Here only the table has an ID, so a selector that takes the second td that is a descendant of that ID and finds the a element should work:
session.click('#table_webbookmarkline_2 td:nth-child(2) a')
I have the following HTML:
<tbody role="alert" aria-live="polite" aria-relevant="all"
<tr class="odd">
<td class="">program user</td>
<td class="">program pass</td>
<td class="">program email</td>
<td class="">Program User</td>
<td class="">
<span class="ui-icon ui-icon-closethick"></span>
</td>
</tr>
<tr class="even">
<td class="">progman</td>
<td class="">progman_name</td>
<td class="">progman_lastname</td>
<td class="">Program Manager</td>
<td class="">
<span class="ui-icon ui-icon-closethick"></span>
This displays a table of users and:
<span class="ui-icon ui-icon-closethick"></span>
is the button 'x', which I am trying to locate so I can delete the user, a specific user 'Program Manager' or 'Program User'
Is this possible?
I assume that you are trying to find a specific user (for which you already know the name) and click on the associated delete button. Something like this should work:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("your-url-here")
elem = driver.find_element_by_xpath("//tbody/td[text()='your-name-here']/../span")
elem.click()
driver.close()
Well I found the solution:
one = driver.find_element_by_xpath("//td[#class='' and text()='Program Manger']/..//span[#class='ui-icon ui-icon-closethick']")
ActionChains(driver).double_click(one).perform()
Basically the I find the class containing text "Program Manager" then I move up to its parent, then iteratively ie. with // look for the 'ui-icon ui-icon-closethick'
And it worked!