Comment analyser une table HTML en utilisant jsoup?
J'essaie d'analyser HTML en utilisant jsoup. C'est la première fois que je travaille avec jsoup et j'ai lu un tutoriel à ce sujet. Voici ma table HTML que j'essaie d'analyser -
Si vous voyez ma table ci-dessous, elle a trois tr
à partir de Maintenant (je l'ai raccourci pour avoir trois lignes de table juste pour comprendre mais en général ce sera plus). Maintenant, je voudrais extraire Cluster Name
de ma table ci-dessous et c'est correspondant host name
donc par exemple - j'extrairais Titan
en tant que cluster nom et tout son nom d'hôte dont le statut est en panne.
Comme vous pouvez le voir ci-dessous pour Titan
nom du cluster, j'ai deux noms d'hôtes machineA.abc.com
et machineB.abc.com
où machineA
statut est up
, mais machineB
statut est down
.
Donc, je vais imprimer Titan
comme nom de cluster et imprimer machineB.abc.com
comme nom d'hôte car il est en panne. Est - ce possible de faire en utilisant jsoup?
<table border=1>
<tr>
<td> </td>
<td> </td>
<td>Alert</td>
<td>Cluster Name</td>
<td>IP addr</td>
<td>Host Name</td>
<td>Type</td>
<td>Status</td>
<td>Free</td>
<td>Version</td>
<td>Restart Time</td>
<td>UpTime(Days)</td>
<td>Last probed</td>
<td>Last up</td>
</tr>
<tr bgcolor="ffffff">
<td><a href=showlog?ip_addr=127.0.0.1>Hist</a></td>
<td><a href=http://127.0.0.1:8080/test?full=y>VI</a></td>
<td bgcolor="ffffff"> </td>
<td>Titan</td>
<td>10.100.111.77</td>
<td>machineA.abc.com</td>
<td></td>
<td bgcolor="ffffff">up</td>
<td bgcolor="ffffff" align=right>88%</td>
<td bgcolor="ffffff">2.0.5-SNAPSHOT</td>
<td bgcolor="ffffff">2014-07-04 01:49:08,220</td>
<td bgcolor="ffffff" align=right>381</td>
<td>07-14 20:01:59</td>
<td>07-14 20:01:59</td>
</tr>
<tr bgcolor="ffffff">
<td><a href=showlog?ip_addr=127.0.0.1>Hist</a></td>
<td><a href=http://127.0.0.1:8080/test?full=y>VI</a></td>
<td bgcolor="ffffff"> </td>
<td></td>
<td>10.200.192.99</td>
<td>machineB.abc.com</td>
<td></td>
<td bgcolor="ffffff">down</td>
<td bgcolor="ffffff" align=right>85%</td>
<td bgcolor="ffffff">2.0.5-SNAPSHOT</td>
<td bgcolor="ffffff">2014-07-04 01:52:20,613</td>
<td bgcolor="ffffff" align=right>103</td>
<td>07-14 20:01:59</td>
<td>07-14 20:01:59</td>
</tr>
</table>
Jusqu'à présent, je suis capable d'extraire toute la table HTML en utilisant jsoup mais je ne sais pas comment extraire le nom du cluster et les noms d'hôtes qui sont en baisse -
URL url = new URL("url_name");
Document doc = Jsoup.parse(url, 3000);
Mise à Jour:-
Je pourrais avoir deux noms de cluster dans la table comme indiqué ci-dessous -
<table border=1>
<tr>
<td> </td>
<td> </td>
<td>Alert</td>
<td>Cluster Name</td>
<td>IP addr</td>
<td>Host Name</td>
<td>Type</td>
<td>Status</td>
<td>Free</td>
<td>Version</td>
<td>Restart Time</td>
<td>UpTime(Days)</td>
<td>Last probed</td>
<td>Last up</td>
</tr>
<tr bgcolor="ffffff">
<td><a href=showlog?ip_addr=127.0.0.1>Hist</a></td>
<td><a href=http://127.0.0.1:8080/test?full=y>VI</a></td>
<td bgcolor="ffffff"> </td>
<td>Titan</td>
<td>10.100.111.77</td>
<td>machineA.abc.com</td>
<td></td>
<td bgcolor="ffffff">up</td>
<td bgcolor="ffffff" align=right>88%</td>
<td bgcolor="ffffff">2.0.5-SNAPSHOT</td>
<td bgcolor="ffffff">2014-07-04 01:49:08,220</td>
<td bgcolor="ffffff" align=right>381</td>
<td>07-14 20:01:59</td>
<td>07-14 20:01:59</td>
</tr>
<tr bgcolor="ffffff">
<td><a href=showlog?ip_addr=127.0.0.1>Hist</a></td>
<td><a href=http://127.0.0.1:8080/test?full=y>VI</a></td>
<td bgcolor="ffffff"> </td>
<td></td>
<td>10.200.192.99</td>
<td>machineB.abc.com</td>
<td></td>
<td bgcolor="ffffff">down</td>
<td bgcolor="ffffff" align=right>85%</td>
<td bgcolor="ffffff">2.0.5-SNAPSHOT</td>
<td bgcolor="ffffff">2014-07-04 01:52:20,613</td>
<td bgcolor="ffffff" align=right>103</td>
<td>07-14 20:01:59</td>
<td>07-14 20:01:59</td>
</tr>
<tr bgcolor="ffffff">
<td><a href=showlog?ip_addr=127.0.0.1>Hist</a></td>
<td><a href=http://127.0.0.1:8080/test?full=y>VI</a></td>
<td bgcolor="ffffff"> </td>
<td>Goldy</td>
<td>10.100.111.77</td>
<td>machineH.pqr.com</td>
<td></td>
<td bgcolor="ffffff">up</td>
<td bgcolor="ffffff" align=right>88%</td>
<td bgcolor="ffffff">2.0.5-SNAPSHOT</td>
<td bgcolor="ffffff">2014-07-04 01:49:08,220</td>
<td bgcolor="ffffff" align=right>381</td>
<td>07-14 20:01:59</td>
<td>07-14 20:01:59</td>
</tr>
</table>
Maintenant, si vous voyez ci-dessus, j'ai deux nom de cluster est Titan
et que l'autre est Goldy
, donc je veux trouver toutes les machines qui sont en bas pour Titan
nom du cluster seulement.
2 réponses
Oui, c'est possible avec JSoup. Tout d'abord, vous sélectionnez la table. Ensuite, vous sélectionnez les balises <tr>
pour les lignes. Vous pouvez commencer à partir du deuxième index puisque la première ligne ne contient que les noms des colonnes. Ensuite, faites une boucle sur les balises <th>
et obtenez l'index spécifique. Dans votre cas, les index 7 et 5 sont importants(index 7: statut, index 5: Nom D'hôte). Vérifiez l'état s'il est égal à down
et si c'est le cas, ajoutez le nom D'hôte à une liste. C'est tout.
ArrayList<String> downServers = new ArrayList<>();
Element table = doc.select("table").get(0); //select the first table.
Elements rows = table.select("tr");
for (int i = 1; i < rows.size(); i++) { //first row is the col names so skip it.
Element row = rows.get(i);
Elements cols = row.select("td");
if (cols.get(7).text().equals("down")) {
downServers.add(cols.get(5).text());
}
}
Mise à Jour:
Lorsque vous trouvez la word Titan
vous pouvez créer une autre boucle et vérifier si le nom du cluster est vide.
Edit: j'ai changer le while
boucle do while
boucle.
ArrayList<String> downServers = new ArrayList<>();
Element table = doc.select("table").get(0); //select the first table.
Elements rows = table.select("tr");
for (int i = 1; i < rows.size(); i++) { //first row is the col names so skip it.
Element row = rows.get(i);
Elements cols = row.select("td");
if (cols.get(3).text().equals("Titan")) {
if (cols.get(7).text().equals("down"))
downServers.add(cols.get(5).text());
do {
if(i < rows.size() - 1)
i++;
row = rows.get(i);
cols = row.select("td");
if (cols.get(7).text().equals("down") && cols.get(3).text().equals("")) {
downServers.add(cols.get(5).text());
}
if(i == rows.size() - 1)
break;
}
while (cols.get(3).text().equals(""));
i--; //if there is two Titan names consecutively.
}
}
Downservers ArrayList contiendra la liste des noms d'hôtes des serveurs down.
Ce que je ferais dans votre cas est d'abord de créer un objet de votre machine avec tous les attributs appropriés. Ensuite, en utilisant Jsoup, j'extrayerais des données et créerais une ArrayList, puis j'utiliserais la logique pour obtenir des données de L'Arraylist.
Je saute la création D'objet (puisque ce n'est pas le problème ici) et je nommerai l'objet comme Machine
Ensuite, en utilisant Jsoup, j'obtiendrais les données de ligne comme ceci:
ArrayList<Machine> list = new ArrayList();
Document doc = Jsoup.parse(url, 3000);
for (Element table : doc.select("table")) { //this will work if your doc contains only one table element
for (Element row : table.select("tr")) {
Machine tmp = new Machine();
Elements tds = row.select("td");
tmp.setClusterName(tds.get(3).text());
tmp.setIp(tds.get(4).text());
tmp.setStatus(tds.get(7).text());
//.... and so on for the rest of attributes
list.add(tmp);
}
}
Ensuite, utilisez une boucle pour obtenir les valeurs dont vous avez besoin liste:
for(Machine x:list){
if(x.getStatus().equalsIgnoreCase("up")){
//machine with UP status found
System.out.println("The Machine with up status is:"+x.getHostName());
}
}
C'est tout. Veuillez également noter que ce code n'est pas testé et peut contenir des erreurs syntaxiques car il est écrit directement sur cet éditeur et non dans un IDE.