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.commachineA 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>&nbsp;</td>
      <td>&nbsp;</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">&nbsp</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">&nbsp</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>&nbsp;</td>
      <td>&nbsp;</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">&nbsp</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">&nbsp</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">&nbsp</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.

25
demandé sur john 2014-07-16 09:29:03

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.

31
répondu user2640782 2014-07-17 06:18:51

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.

5
répondu MaVRoSCy 2014-07-16 06:02:37