Je souhaite extraire des données d'une table, en prenant toute la ligne Le html ressemble à ceci (il y a plus de 2 lignes): J'ai utilisé this mais la réponse ici donne toutes les lignes d'une table au lieu de lignes qui contiennent l'attribut nécessaire Donc, mon code pour l'instant ressemble à: p > puis je racle à nouveau le site pour trouver l'attribut bgcolor, l'ajouter à la liste, ajouter la liste au cadre et supprimer toute ligne qui n'a pas la bonne couleur bg. Tout cela est assez inefficace Comment puis-je gratter le html pour prendre des lignes de la table uniquement si bgcolor existe dans td.attrs de la ligne EDIT: Une fois les solutions ci-dessous sont appliqués à l'ensemble du html, le script renvoie des listes vides (et c'est ma faute de ne pas inclure plus de html). Ce html ci-dessous est une version plus complète où plus de balises sont incluses. Il est également intéressant de noter que j'utilise urllib.request pour ouvrir l'url puis l'analyse avec BS s'il y a un
dans la ligne <html><head><title></title><style type="text/css">
BODY {
font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #FFFFFF
;}TABLE {
font-family: Tahoma, Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 11px;
background-color: #FFFFFF;}
DIV.boldText {
font-size: 11px;font-weight: bold;
}
</style>
<meta http-equiv="REFRESH" content="10">
</head><body>
<form name="DataViewChooser">
<hr width="95%" align="CENTER" color="#55aa2a">
<table width="95%" align="CENTER">
<tbody><tr><td width="40" height="65" title="(c) ITEMS"><img
src="/icons/geneos_logo.png"></td>
<td width="25" align="LEFT">
<img title="Refresh" style="cursor: hand;" onclick="reloadPage()"
src="/icons/refresh.png"></td>
<td width="25" title="Show Fail and Warning Only" align="LEFT"><img
style="cursor: hand;" onclick="userContractView()" src="/icons/minimise.png"></td>
<td width="25" align="LEFT"><img title="Home" style="cursor: hand;" onclick="goHome()" src="/icons/up.png"></td>
<td align="RIGHT" nowrap="NOWRAP"><img src="/icons/hostgreen.gif">
<div class="boldText"> DASHBOARD-CV_AMER_Dashboard</div> [GROUP]
</td>
</tr></tbody></table><hr width="95%" align="CENTER" color="#55aa2a"></form>
<br><table width="95%" align="CENTER"><tbody><tr><td><table>
<tbody><tr><th height="20" align="LEFT" nowrap="NOWRAP"> AMER
</th>
<td nowrap="NOWRAP" bgcolor="#55aa2a"> </td></tr>
</tbody></table></td></tr></tbody></table>
<br><table width="99%" align="CENTER">
<tbody><tr bgcolor="#c0c0c0">
<th height="20" align="LEFT" nowrap="NOWRAP"> RowName </th>
<th height="20" align="LEFT" nowrap="NOWRAP"> Gateway_updatetime
</th>
<th height="20" align="LEFT" nowrap="NOWRAP"> Gateway_state </th>
<th height="20" align="LEFT" nowrap="NOWRAP"> OrdersCleared </th>
<th height="20" align="LEFT" nowrap="NOWRAP"> Ticketsread </th>
<th height="20" align="LEFT" nowrap="NOWRAP"> OrdersNotCleared
</th>
<th height="20" align="LEFT" nowrap="NOWRAP"> TicketsNotCleared
</th>
<th height="20" align="LEFT" nowrap="NOWRAP"> LastReadingtime
</th>
<th height="20" align="LEFT" nowrap="NOWRAP"> LastClearingtime
</th>
<th height="20" align="LEFT" nowrap="NOWRAP"> ClearingInProgress
</th>
<th height="20" align="LEFT" nowrap="NOWRAP"> YestVolumes </th>
<th height="20" align="LEFT" nowrap="NOWRAP"> Starttime </th>
<th height="20" align="LEFT" nowrap="NOWRAP"> Stoptime </th>
</tr><tr bgcolor="#f4f4f4">
<td height="25" nowrap="NOWRAP"> ITEM_4 </td>
<td height="25" nowrap="NOWRAP"> 07:58:46 </td>
<td height="25" nowrap="NOWRAP"> Connected </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 07:58:00 </td>
<td height="25" nowrap="NOWRAP" bgcolor="#d42a2a"> --:--:-- </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 01:25:00 </td>
<td height="25" nowrap="NOWRAP"> 22:00:00 </td>
</tr>
<tr bgcolor="#ffffff">
<td height="25" nowrap="NOWRAP"> ITEM_5 </td>
<td height="25" nowrap="NOWRAP"> 07:58:46 </td>
<td height="25" nowrap="NOWRAP"> Connected </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 191 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 07:58:01 </td>
<td height="25" nowrap="NOWRAP" bgcolor="#55aa2a"> --:--:-- </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 01:25:00 </td>
<td height="25" nowrap="NOWRAP"> 22:00:00 </td>
</tr>
</tbody></table><script language="JavaScript" src="/cookie.js"></script>
</body></html>'''
data = []
rows = table_body.find_all('tr')
for row in rows:
cols = row.find_all('td')
cols = [ele.text.strip() for ele in cols]
data.append([ele for ele in cols if ele])
<tr bgcolor="#f4f4f4">
<td height="25" nowrap="NOWRAP"> ITEM_1 </td>
<td height="25" nowrap="NOWRAP"> 07:58:46 </td>
<td height="25" nowrap="NOWRAP"> Connected </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 07:58:00 </td>
<td height="25" nowrap="NOWRAP" bgcolor="#55aa2a"> --:--:-- </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 01:25:00 </td>
<td height="25" nowrap="NOWRAP"> 22:00:00 </td>
</tr>
<tr bgcolor="#ffffff">
<td height="25" nowrap="NOWRAP"> ITEM_2 </td>
<td height="25" nowrap="NOWRAP"> 07:58:46 </td>
<td height="25" nowrap="NOWRAP"> Connected </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 191 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 07:58:01 </td>
<td height="25" nowrap="NOWRAP" bgcolor="#55aa2a"> --:--:-- </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 01:25:00 </td>
<td height="25" nowrap="NOWRAP"> 22:00:00 </td>
</tr>
<tr bgcolor="#ffffff">
<td height="25" nowrap="NOWRAP"> ITEM_3 </td>
<td height="25" nowrap="NOWRAP"> 07:59:02 </td>
<td height="25" nowrap="NOWRAP"> Connected </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 36 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 36 </td>
<td height="25" nowrap="NOWRAP"> 07:58:01 </td>
<td height="25" nowrap="NOWRAP" bgcolor="#d42a2a"> --:--:-- </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 0 </td>
<td height="25" nowrap="NOWRAP"> 03:10:00 </td>
<td height="25" nowrap="NOWRAP"> 22:00:00 </td>
</tr>
3 Réponses :
Vous pouvez utiliser any
:
[<tr bgcolor="#ffffff"> <td height="25" nowrap="NOWRAP"> ITEM_3 </td> <td height="25" nowrap="NOWRAP"> 07:59:02 </td> <td height="25" nowrap="NOWRAP"> Connected </td> <td height="25" nowrap="NOWRAP"> 0 </td> <td height="25" nowrap="NOWRAP"> 36 </td> <td height="25" nowrap="NOWRAP"> 0 </td> <td height="25" nowrap="NOWRAP"> 36 </td> <td height="25" nowrap="NOWRAP"> 07:58:01 </td> <td bgcolor="#d42a2a" height="25" nowrap="NOWRAP"> --:--:-- </td> <td height="25" nowrap="NOWRAP"> 0 </td> <td height="25" nowrap="NOWRAP"> 0 </td> <td height="25" nowrap="NOWRAP"> 03:10:00  </td> <td height="25" nowrap="NOWRAP"> 22:00:00 </td> </tr>]
Output:
from bs4 import BeautifulSoup as soup d = soup(content, 'html.parser') results = [i for i in d.find_all('tr') if any(c.attrs.get('bgcolor') == "#d42a2a" for c in i.find_all('td'))]
Vous pouvez éviter d'utiliser find_all ()
+ any ()
comme vous pouvez simplement faire l'opération .find ()
directement.
Cela a fonctionné parfaitement! Je sélectionne autre comme réponse car il s'agit d'une doublure.
@swagless_monk Heureux de vous aider! C'est aussi un one-liner, pensa-t-il. table_body
dans la réponse d'alecxe est un objet BeautifulSoup
tel que soup (content, 'html.parser')
qui doit être initialisé sur une ligne différente . Si vous voulez une solution sur une seule ligne, remplacez d
par soup (content, 'html.parser')
dans la compréhension.
Vous pouvez appliquer une fonction de recherche em > où vous pouvez vérifier que le nom de la balise est tr
ainsi que vérifier que la ligne contient un élément td
avec bgcolor = "# D42A2A "
:
[tr for tr in table_body('tr') if tr.find('td', bgcolor="#D42A2A")]
Vous pouvez bien sûr faire la même vérification dans une liste de compréhension directement:
def rows_with_desired_bgcolor(elm): return elm.name == 'tr' and elm.find('td', bgcolor="#D42A2A") table_body.find_all(rows_with_desired_bgcolor)
où table_body ('tr')
est un raccourci vers table_body.find_all('tr')
.
J'aime votre compréhension de liste, mais cela produit une liste vide
@swagless_monk ok, avez-vous essayé de mettre en minuscules la valeur bgcolor
?
Possible d'obtenir uniquement du texte? J'utilise tr.text
, mais j'ai besoin de quelque chose comme tr.strip
@swagless_monk vous pourriez faire .get_text (strip = True)
Je suppose.
trouver tout td
contient bgcolor = "# d42a2a"
puis sélectionner le .parent
cells = table_body.find_all('td', bgcolor="#d42a2a") for cell in cells: print(cell.parent) # <tr>...<td bgcolor="#d42a2a">...</tr>
p >
Avez-vous testé et c'est le résultat que vous avez obtenu?
Je suis certain que ce n'est pas votre code, mais mon env. Permettez-moi de modifier encore
Cela a très bien fonctionné, merci! J'ai sélectionné @alecxe comme réponse car c'est une ligne