Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 5 sur 5
  1. #1
    Invité régulier
    Inscrit en
    avril 2010
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 45
    Points : 6
    Points
    6

    Par défaut Parser HTML avec Cobra et récupérer du blanc via XPath

    Bonjour à tous,

    J'ai posé la question également dans la rubrique Swing/Awt, mais à la réflexion, je pense que c'est plus adapté de poser ici mon problème....

    Alors, voilà je fais du parsing de HTML avec Cobra en utilisant des recherches directement avec XPath.

    Je m'appuie pour ce faire sur l'exemple donné dans leur site et repris ci-dessous:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.net.URL;
    import javax.xml.xpath.*;
    import javax.xml.parsers.*;
    import java.util.logging.*;
     
    import org.lobobrowser.html.UserAgentContext;
    import org.lobobrowser.html.parser.*;
    import org.lobobrowser.html.test.SimpleUserAgentContext;
    import org.w3c.dom.NodeList;
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
     
    public class ParseAnchorsTest {
        private static final String TEST_URI = "http://lobobrowser.org";
     
        public static void main(String[] args) throws Exception {
            // Disable most Cobra logging.
            Logger.getLogger("org.lobobrowser").setLevel(Level.WARNING);
            UserAgentContext uacontext = new SimpleUserAgentContext();
            // In this case we will use a standard XML document
            // as opposed to Cobra's HTML DOM implementation.
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            URL url = new URL(TEST_URI);
            InputStream in = url.openConnection().getInputStream();
            try {
                Reader reader = new InputStreamReader(in, "ISO-8859-1");
                Document document = builder.newDocument();
                // Here is where we use Cobra's HTML parser.            
                HtmlParser parser = new HtmlParser(uacontext, document);
                parser.parse(reader);
                // Now we use XPath to locate "a" elements that are
                // descendents of any "html" element.
                XPath xpath = XPathFactory.newInstance().newXPath();
                NodeList nodeList = (NodeList) xpath.evaluate("//table/tr/td/child::text()", document, XPathConstants.NODESET);
                ...
            } finally {
                in.close();
            }
        }
    }
    A la différence près que je cherche les tables et non les liens. J'ai donc créé une instruction XPath pour ça:

    Code :
    //table/tr/td/child::text()"
    Le problème, c'est que si dans une des cellules de ma table j'ai du vide, l'instruction XPath ne me le remontera pas.

    Avez-vous une solution...je cale !

  2. #2
    Modérateur
    Avatar de polymorphisme
    Homme Profil pro Grégory Roche
    Publishing
    Inscrit en
    octobre 2009
    Messages
    1 438
    Détails du profil
    Informations personnelles :
    Nom : Homme Grégory Roche
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Publishing

    Informations forums :
    Inscription : octobre 2009
    Messages : 1 438
    Points : 2 322
    Points
    2 322

    Par défaut

    Bonjour,

    en effet, si une cellule ne contient pas de texte alors l'expression Xpath est évaluée avec la valeur nulle.

    Pour tester si le texte est vide, tu peux utiliser l'expression :
    Code :
    //table/tr/td/child::text()=''
    Article : Installation de Cocoon
    Je ne réponds pas aux MP à caractère technique.

  3. #3
    Invité régulier
    Inscrit en
    avril 2010
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 45
    Points : 6
    Points
    6

    Par défaut

    J'ai testé, mais ça ne marche pas dans mon exemple...

    En fait, j'ai changé d'approche. Mon but est de récupérer la table HTML en prenant chaque balise (<table>, <tr>, <td>) afin de constituer un document DOM à l'issue du parsing.
    J'utilise le parseur XPath fourni avec le JDK 5.

    Je procède ainsi:

    Je commence par filtrer les tables qui m'intéresse par l'instruction XPath ("//table[@class='simple']") qui me renvoie 2 noeuds.
    Je boucle ensuite sur ce premier résultat, définit comme noeud courant la première table, et cherche ensuite les lignes via l'expression XPath ("./tr"), en passant le noeud courant en paramètre.
    Je récupère 7 lignes (valeur de lengthRow), je positionne le noeud courant sur la première ligne et je recommence pour récupérer les cellules via l'expression XPath ("./td") toujours en passant le noeud courant en contexte.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
            XPath xpa = XPathFactory.newInstance().newXPath();
            NodeList nodeList = (NodeList) xpa.evaluate("//table[@class='simple']", document, XPathConstants.NODESET);
            int length = nodeList.getLength();
            Element noeudCourant = null;
            for (int i = 0; i < length; i++) {
                noeudCourant = (Element) nodeList.item(i);
                NodeList nodeListRow = (NodeList) xpa.evaluate("./tr", noeudCourant, XPathConstants.NODESET);
                int lengthRow = nodeListRow.getLength();
                for (int j = 0; j < lengthRow; j++) {
                    System.out.println("j: " + j);
                    noeudCourant = (Element) nodeListRow.item(j);
                    NodeList nodeListCell = (NodeList) xpa.evaluate("./td", noeudCourant, XPathConstants.NODESET);
                    int lengthCell = nodeListCell.getLength();
    ...}
    }
    et ça a l'air de marcher !

  4. #4
    Modérateur
    Avatar de polymorphisme
    Homme Profil pro Grégory Roche
    Publishing
    Inscrit en
    octobre 2009
    Messages
    1 438
    Détails du profil
    Informations personnelles :
    Nom : Homme Grégory Roche
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Publishing

    Informations forums :
    Inscription : octobre 2009
    Messages : 1 438
    Points : 2 322
    Points
    2 322

    Par défaut

    Bonjour,

    fait attention du fait que tu utilise du HTML ... qui n'est pas du XML.
    Article : Installation de Cocoon
    Je ne réponds pas aux MP à caractère technique.

  5. #5
    Invité régulier
    Inscrit en
    avril 2010
    Messages
    45
    Détails du profil
    Informations forums :
    Inscription : avril 2010
    Messages : 45
    Points : 6
    Points
    6

    Par défaut

    Oui, je me suis déjà rendu compte qu'il fallait faire attention au fait qu'on avait du HTML et non du XML. J'ai constaté ça quand j('ai essayé d'utiliser l'API JDOM...

    Là, dans le cas présent, si je parse mon flux HTML en entrée, je ne vois pas ce qui peut m'empêcher de créer ensuite un document DOM avec pour balises, les balises HTML pour les tables et ensuite sérialiser btout ça dans un fichier ...

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •