Utilisation de la classe StringExtractor

Fermé
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013 - 21 janv. 2013 à 11:48
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013 - 21 janv. 2013 à 17:26
Bonjour,

Je souhaite récupérer le contenu texte d'une page web. Pour cela, j'ai tenté d'utiliser la fonction extractStrings de la classe StringExtractor. Mais le type StringExtractor n'est pas reconnu. Comment le définir ?

merci d'avance pour vos réponses.

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.lang.Object;

public class test {

public static String CopyText(String URL) {

StringExtractor se = new StringExtractor(URL);
String contents = se.extractStrings(true);
Pattern p = Pattern.compile("<[^>]*>");
Matcher m = p.matcher(contents);

String text = m.replaceAll(" ");

return text;
}

public static void main(String[] args) {
String URL = "http://htmlparser.sourceforge.net";
String extrait = "";

extrait = CopyText(URL);
System.out.println("l'extrait de la page web est:");
System.out.println(""+extrait);
}

}

6 réponses

KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
21 janv. 2013 à 12:20
StringExtractor n'est pas une classe standard de Java, si tu utilises une bibliothèque complémentaire réfères toi à sa documentation, mais je pense qu'il est tout à fait possible de faire ce que tu veux avec les classes standards. Il va juste falloir expliquer quel résultat tu souhaiterais obtenir avec ton "<[^>]*>"

Exemple (affiche tout le contenu de la page, sauf ce qui est entre balise <>)

import java.net.URL;
import java.util.Scanner;

public class TestParser 
{
	public static void main(String[] args) throws Exception 
	{
		String spec = "http://htmlparser.sourceforge.net";
		Scanner sc = new Scanner(new URL(spec).openStream());
		sc.useDelimiter("<[^>]*>");
		
		while (sc.hasNext())
			System.out.println(sc.next());
		sc.close();
	}
}
0
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013
21 janv. 2013 à 12:34
J'aimerais récupérer juste la partie utile de la page web, c'est-à-dire enlever du code source les éléments qui ne servent pas (balises, éléments de menu, etc...). Idéalement, j'aimerais récupérer un texte cohérent d'une taille limitée.
0
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
21 janv. 2013 à 12:43
Donc avec mon Scanner je n'étais pas trop mal parti, il faudrait juste enlever les lignes vides qui s'accumulent :

import java.net.URL;
import java.util.Scanner;

public class TestParser 
{
    public static void main(String[] args) throws Exception 
    {
        String spec = "http://htmlparser.sourceforge.net";
        Scanner sc = new Scanner(new URL(spec).openStream());
        
        while (sc.hasNextLine())
        {
            String line = sc.nextLine().replaceAll("<[^>]*>", "");
            if (!line.trim().isEmpty())
                System.out.println(line);
        }
        sc.close();
    }
}
0
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013
21 janv. 2013 à 14:18
Merci, ça fonctionne !
Aurais-tu une idée pour enlever tout ce qui est titre, date de publication, menu ?
0
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
21 janv. 2013 à 14:31
Ce que j'ai fait c'est un traitement automatique très général, on voit une balise, on l'enlève.
S'il faut prendre en compte le "sens" de chaque balise, il va falloir spécialiser le traitement, mais on va perdre en généralité.

Exemple : le "menu" dans ta page d'exemple c'est un div "navcolumn", mais sur une autre page web, le menu sera construit autrement donc si le navcolumn existe il sera elenvé alors que ce n'était pas un menu, et le vrai menu qui sera autre chose qu'un navcolumn ne sera pas enlevé...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013
21 janv. 2013 à 14:41
OK, je vois.
Ce qui m'importe, c'est d'avoir un contenu propre. Si je perds du contenu en croyant que c'était un menu ou autre, ce n'est pas grave. De toutes façons, j'aimerais ne récupérer qu'une petite partie de la page web (style un paragraphe).
0
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
21 janv. 2013 à 15:32
Normalement les paragraphes sont entre balises <p></p> on pourrait éventuellement ne récupérer que ce genre de contenu, même si c'est assez restrictif :

String spec = "http://htmlparser.sourceforge.net";
Scanner sc = new Scanner(new URL(spec).openStream());

sc.useDelimiter("<p>");
while (sc.hasNext())
{
	sc.next();			
	sc.useDelimiter("</p>");
	if (sc.hasNext())
		System.out.println(sc.next().replaceAll("<[^>]*>", ""));			
	sc.useDelimiter("<p>");
}
sc.close();
0
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013
21 janv. 2013 à 17:07
ça fonctionne bien avec certains sites ; avec d'autres, il y a des problèmes d'accents et des   restants.

j'ai besoin de récupérer le contenu de la page dans une variable String. J'ai essayé ça mais ça ne marche pas :

public class test {

public static String CopyText(String adresse) {
Scanner sc = new Scanner(new URL(adresse).openStream());
String resultat = "";
sc.useDelimiter("<p>");
while (sc.hasNext())
{
sc.next();
sc.useDelimiter("</p>");
if (sc.hasNext())
System.out.println(sc.next().replaceAll("<[^>]*>", ""));
resultat = resultat + sc.next().replaceAll("<[^>]*>", "");
sc.useDelimiter("<p>");
}
sc.close();
return resultat;
}

public static void main(String[] args) throws Exception {
String extrait = "";
extrait = CopyText("http://ww5.agent-virtuel.fr");
System.out.println(resultat);

}

}
0
KX Messages postés 16752 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 août 2024 3 019
21 janv. 2013 à 17:23
Effectivement ça ne fonctionne pas comme ça, car on ne peux pas utiliser "sc.next()" deux fois de suite (une fois dans l'affichage, et une fois dans resultat = result +), ça te renverra deux résultats différents et ça va tout décaler. Le moyen le plus simple pour corriger ça c'est d'enlever la ligne d'affichage !

Cependant, plutôt qu'utiliser un String, je te conseilles un StringBuilder, qui sera plus efficace (ça évite de recréer un objet String enj copiant la totalité de ses caractères à chaque fois que tu rajoutes des données)

Pour le problème d'accent, c'est parce que ta page est en UTF-8, il suffit d'indiquer ça à la création du Scanner pour que les accents reviennent.

public static String CopyText(String adresse) throws Exception 
{
    Scanner sc = new Scanner(new URL(adresse).openStream(),"UTF-8");
    StringBuilder sb = new StringBuilder();
    
    sc.useDelimiter("<p>");
    while (sc.hasNext())
    {
        sc.next();
        
        sc.useDelimiter("</p>");
        if (sc.hasNext())
            sb.append(sc.next().replaceAll("<[^>]*>", ""));
        
        sc.useDelimiter("<p>");
    }
    
    sc.close();
    return sb.toString();
}

public static void main(String[] args) throws Exception
{
    String resultat = CopyText("http://ww5.agent-virtuel.fr");
    System.out.println(resultat);
}
0
janroll Messages postés 6 Date d'inscription lundi 21 janvier 2013 Statut Membre Dernière intervention 21 janvier 2013
21 janv. 2013 à 17:26
Je vais essayer de comprendre tout ça, merci !
0