I'm trying to find an account number in a table (it can be in many multiple tables) along with the status of the account. I'm trying to utilize find_element using the Xpath and the odd thing is that it is saying it cannot find it. You can see in the html that the id exists yet it is defaulting to my except saying table not found. My end result is to find the table that has the header Instance ID with the value of 9083495r3498q345 and to give the value under the Status field for that row in the same table. Please keep in mind that it may not be DataTables_Table_6 but could be DataTables_Table_i
<table class="data-table clear-both dataTable no-footer" cellspacing="0" id="DataTables_Table_6" role="grid">
<thead>
<tr role="row"><th style="text-align: left; width: 167.104px;" class="ui-state-default sorting_disabled" rowspan="1" colspan="1"><div class="DataTables_sort_wrapper"><span class="DataTables_sort_icon"></span>Parent Instance ID</div></th><th style="text-align: left; width: 116.917px;" class="ui-state-default sorting_disabled" rowspan="1" colspan="1"><div class="DataTables_sort_wrapper"><span class="DataTables_sort_icon"></span>Instance ID</div></th><th style="text-align: left; width: 97.1771px;" class="ui-state-default sorting_disabled" rowspan="1" colspan="1"><div class="DataTables_sort_wrapper"><span class="DataTables_sort_icon"></span>Plan Name</div></th><th style="text-align: left; width: 168.719px;" class="ui-state-default sorting_disabled" rowspan="1" colspan="1"><div class="DataTables_sort_wrapper"><span class="DataTables_sort_icon"></span>Client Defined Identifier</div></th><th style="text-align: left; width: 39.5729px;" class="ui-state-default sorting_disabled" rowspan="1" colspan="1"><div class="DataTables_sort_wrapper"><span class="DataTables_sort_icon"></span>Units</div></th><th style="text-align: left; width: 89.8438px;" class="ui-state-default sorting_disabled" rowspan="1" colspan="1"><div class="DataTables_sort_wrapper"><span class="DataTables_sort_icon"></span>Status</div></th></tr>
</thead>
<tbody>
<tr role="row" class="odd">
<td style="text-align: left;"><span style="padding-left:px;\"><a href="#" class="doAccountsPanel" ></a></span></td>
<td style="text-align: left;"><span style="padding-left:px;\">Not Needed</span></td>
<td style="text-align: left;">The Product</td>
<td style="text-align: left;">9083495r3498q345</td>
<td style="text-align: left;">1</td>
<td style="text-align: left;">Suspended</td>
</tr></tbody></table>
try:
driver_chrom.find_element(By.XPATH,'//*[#id="DataTables_Table_6"]')
print("Found The Table")
except:
print("Didn't find the table")
I would have expected my print result to be "Found the Table", but I'm getting the "Didn't find the table".
DataTables are dynamic elements - the actual info they hold is being hydrated by javascript on an empty table skeleton, after page loads. Therefore, you need to wait for the table to fully load, then look up the information it holds:
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, 20)
[...]
desired_info = wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="DataTables_Table_6"]')))
print(desired_info.text)
See Selenium documentation here.
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 have a PyQt6 application that features a custom text editor.
When user hovers some word in this editor, a custom QToolTip is displayed.
I would have liked to make it fancier than the default one, with the following structure:
******* TITLE
* *
* IMG * - some text
* * - some other text
*******
I'm really noobish when it comes to HTML. I tried some code using <div> and <p> blocks, it delivered what I wanted when loading it in a navigator, but the result was not as expected in the application.
From what it seems, despite the documentation stating that Qt supports HTML blocks, what I want to achieve might be impossible.
Do you guys have any clue on what I could do to make it work? Above is an example of what I tried.
<div style="background-color: #2F3135;font-family: Franklin Gothic;font-size: 12;">
<div style="float: left;background-color: #2F3135;padding: 30px 20px 30px 30px;"><img src=MY_IMAGE width="64" height="64"/>
</div>
<p style="color: #FFFFFF;line-height:135%"><b><span style="background-color: #009900">TITLE:</b></span><br>
<span style="background-color: #009900;">some text<br></span>
<span style="background-color: #009900;">some other text<br></span>
</p>
</div>
EDIT
Following the answer from musicamante, I tried to do a table rather than using div blocks.
As I say in my answer to him, it works except if the title word of the second row is too long. Above should be a reproducable QTooltip example:
<table style="background-color: #454850;">
<tr>
<th rowspan=7 style="vertical-align: middle;padding-left: 20px;padding-right: 15px"><img src=MYIMAGE width="64" height="64"/></th>
<th><b><span style="color: #CECED7;font-family: Verdana, sans-serif;font-size: 10;">MAIN_TITLE</span></b></th>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td><b><span style="background-color: #307D30;color: #BACABA;font-family: Verdana, sans-serif;font-size: 10;">Inputs:</b></span></td>
</tr>
<tr>
<td><span style="background-color: #913131;color: #D0BFBF;font-family: Verdana, sans-serif;font-size: 10;">blabla</span></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td><b><span style="background-color: #913131;color: #D0BFBF;font-family: Verdana, sans-serif;font-size: 10;">Outputs:</b></td>
</tr>
<tr>
<td><span style="background-color: #913131;color: #D0BFBF;font-family: Verdana, sans-serif;font-size: 10;">blabla</span></td>
</tr>
</table>
So if MAIN_TITLE > 32 characters in my case, the 2nd column will not display properly in the QToolTip.
Maybe I messed up in the HTML code (I'm very new to HTML, never really worked with it).
Any tips is welcomed!
The structure of the website I'm trying to parse looks like this:
<table border="0" cellpadding="3" cellspacing="0" width="100%">
<tr height="25">
<td class="th" style="border:none" width="2%"> </td>
<td class="th">movie</td>
<td class="th"> </td>
<td class="th"> </td>
</tr>
<tr id="place_1">
<td style="color: #555; vertical-align: top; padding: 6px">
<a name="1"></a>1.
</td>
<td style="height: 27px; vertical-align: middle; padding: 6px 30px 6px 0">
<a class="all" href="/326/">MOVIE TITLE IN SPANISH</a>
<br/>
<span class="text-grey">MOVIE TITLE IN ENGLISH</span>
</td>
<td style="width: 85px">
<div style="width: 85px; position: relative">
<a class="continue" href="/326/votes/">
9.191
</a>
<span style="color: #777">
(592 184)
</span>
</div>
</td>
</tr>
...
...
...
The problem is I can't get the text inside span-tag. I've tried .text as for a-tag, also tried .get_text(). But none of these worked. My code on Python:
for row in table.find_all('tr')[1:]:
info = row.find_all('td')
movies.append({
'spn_title' : info[1].a.text,
'eng_title' : info[1].span.text,
})
The errors I get:
AttributeError: 'NoneType' object has no attribute 'get_text'
or
'eng_title' : info[1].span.text AttributeError: 'NoneType' object has
no attribute 'text'
Try the following. Also, check your soup variable because I can run your code without problem. I suspect that somewhere later in the HTML you don't have one of these present in a row.
If the class names are consistent you could filter only qualifying rows having the appropriate type elements with those classes.Using bs4 4.7.1.
for row in table.select('tr :has(span.text-grey):has(a.all)'):
movies.append({
'spn_title' : row.select_one('.all').text,
'eng_title' : row.select_one('.text-grey').text
})
print(movies)
Otherwise, you want a way to handle if not present. For example,
for row in table.find_all('tr')[1:]:
movies.append({
'spn_title' : row.select_one('.all').text if row.select_one('.all') is not None else 'None',
'eng_title' : row.select_one('.text-grey').text if row.select_one('.text-grey') is not None else 'None'
})
print(movies)
I think that you should use innerHTML.
info[1].getElementsByTagName('span')[0].innerHTML
should work.
I have the same issue but I was able to resolve it.
example
<span class="a-offscreen">$10.99</span>
instead of Elem.FindElementByCss("span.a-offscreen").Text
use:
Elem.FindElementByCss("span.a-offscreen").FindElementByXPath("parent::*").Text
The trick is to get the text of the parent.
Btw, I am using VBA so you need to change it to Python Syntax.
I'm trying to do automation and struck in the middle.
Cannot able to select option from a submenu.
Tried every solution from stack overflow and anything doesn't work.
Attaching the code.
<input id="arid_WIN_0_2000053" class="text " readonly="" style="top: 0px; left: 0px; width: 72px; height: 21px;" title="Screen" type="text">
This is the id i need to click so a drop down appears.
That is from differant section and the code is,
<table class="MenuTable" style="width: 93px;" cellspacing="0" cellpadding="0">
<tbody class="MenuTableBody">
<tr class="MenuTableRow">
<td class="MenuEntryName" nowrap="">Screen</td>
<td class="MenuEntryNoSub" arvalue="Screen"></td>
</tr>
<tr class="MenuTableRow">
<td class="MenuEntryName" nowrap="">File</td>
<td class="MenuEntryNoSub" arvalue="File"></td>
</tr>
<tr class="MenuTableRow">
<td class="MenuEntryName" nowrap="">Printer</td>
<td class="MenuEntryNoSub" arvalue="Printer"></td>
</tr>
<tr class="MenuTableRow">
<td class="MenuEntryNameHover" nowrap="">(clear)</td>
<td class="MenuEntryNoSubHover" arvalue=""></td>
</tr>
</tbody>
</table>
Once i selected the ID arid_WIN_0_2000053, i need to select option as File.
Thanks in advance.
As per the HTML to select an option e.g. File from the submenu you can use either of the following solutions:
driver.find_element_by_xpath("//input[#class='text' and #title='Screen'][starts-with(#id,'arid_WIN_0_')]").click()
driver.find_element_by_xpath("//table[#class='MenuTable']//tr[#class='MenuTableRow']//td[#class='MenuEntryName' and contains(.,'File')]").click()
Or
driver.find_element_by_xpath("//input[#class='text' and #title='Screen'][starts-with(#id,'arid_WIN_0_')]").click()
driver.find_element_by_xpath("//table[#class='MenuTable']//tr[#class='MenuTableRow']//td[#class='MenuEntryNoSub' and #arvalue='File']").click()
Use as Css locator : .MenuTableRow:nth-of-type(2) .MenuEntryName
I am trying to extract some data from a webpage that has multiple tables. All the tables have an id="name" attribute. I am using beautiful soup 4 with Python 3.4.1. My code lopped through the first tables just fine, but on the last one it returns 'None' and I can't figure out why.
The html code for the table info is below and from what I can see, it was not formatted any differently than the other tables that had other id names such as id=Datagrid1
<TR>
<TD vAlign=top>
<TABLE id=Datagrid7
style="FONT-SIZE: smaller; FONT-FAMILY: Verdana; WIDTH: 675px; BORDER-COLLAPSE: collapse"
cellSpacing=0 rules=all align=left border=1>
<TBODY>
The python code below returns None, but will work if I change the id to another known id name.
table = soup.find('table', id='DataGrid7')
print(table)
there was typo error in your program it should be small 'g'
from bs4 import BeautifulSoup
html="""<TR>
<TD vAlign=top>
<TABLE id=Datagrid7
style="FONT-SIZE: smaller; FONT-FAMILY: Verdana; WIDTH: 675px; BORDER-COLLAPSE: collapse"
cellSpacing=0 rules=all align=left border=1>
<TBODY>"""
soup=BeautifulSoup(html)
print soup.find('table',id='Datagrid7')
#output <table align="left" border="1" cellspacing="0" id="Datagrid7" rules="all" style="FONT-SIZE: smaller; FONT-FAMILY: Verdana; WIDTH: 675px; BORDER-COLLAPSE: collapse">
<tbody></tbody></table>
There's a typo in the code.
The id of the table is Datagrid7, not DataGrid7:
table = soup.find('table', id='Datagrid7')
# ^