Récupérer le contenu d'une balise

Signaler
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012
-
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
-
Bonjour,

je cherche à récupérer les valeurs qui sont entre les balises <option> et </options>
c'est à dire :
Texte1
Texte2
Texte3

<form method="post" name="jumpbox" action="./adresse.php" onsubmit="if(document.jumpbox.f.value == -1){return false;}"> 
 
Aller à: <select name="f" onchange="if(this.options[this.selectedIndex].value != -1){ document.forms['jumpbox'].submit() }">

<option value="1">Texte1</option>
<option value="2">texte2</option>
<option value="3">Texte3</option>

</select> 
 
 
</form>


On ma conseiller d'utiliser cette méthode :
 HtmlElementCollection Tables = webBrowser.Document.GetElementsByTagName("table");
            foreach (HtmlElement table in Tables)
            {
                if (table.InnerText.Trim() == "Aller à:")
                {
                    MessageBox.Show(table.InnerText);

                }
            }

mais elle ne fonctionne pas a priori,
quelqu'un aurait une autre idée ?

Merci d'avance

18 réponses

Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
49
Salut

Vu qu'une page web est loin d'être un XML parfaitement en règle, tu ne peux pas utiliser LINQ (dommage, ça aurait été très pratique).
La méthode la plus simple reste, selon moi, les expressions régulières.

Tu peux utiliser, par exemple, cette regex :
<\s*option[^>]*>(?<valeur>([^<]*))</option>

Ce qui nous donne :
string ex = @"<\s*option[^>]*>(?<valeur>([^<]*))</option>";
Regex regex = new Regex(ex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
var resultats = regex.Matches(source);
foreach (Match resultat in resultats)
{
    Console.WriteLine(resultat.Groups["valeur"].Value);
}

Avec ça, tu vas pouvoir récupérer toutes les valeurs des balises <option> de ton documents.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

Merci de ta réponse.
Je vais essayer je te tiens au courant.
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

ça ne fonctionne pas :(
Une idée ?
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
49
"ça ne fonctionne pas :("
Un peu légers comme détails...

Tu as bien pensé à remplacer "source", dans mon code, par le string qui contient ta source HTML ?

Car chez moi, le code marche parfaitement.

using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string source = @"<form method=""post"" name=""jumpbox"" action=""./adresse.php"" onsubmit=""if(document.jumpbox.f.value == -1){return false;}""> 
 
Aller à: <select name=""f"" onchange=""if(this.options[this.selectedIndex].value != -1){ document.forms['jumpbox'].submit() }"">

<option value=""1"">Texte1</option>
<option value=""2"">texte2</option>
<option value=""3"">Texte3</option>

</select> 
 
 
</form>";
            string ex = @"<\s*option[^>]*>(?<valeur>([^<]*))</option>";
            Regex regex = new Regex(ex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            MatchCollection resultats = regex.Matches(source);
            foreach (Match resultat in resultats)
            {
                Console.WriteLine(resultat.Groups["valeur"].Value);
            }
            Console.ReadLine();
        }
    }
}


L'exécution m'affiche bien
Texte1
texte2
Texte3

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

voilà ce que j'ai mis :
string ex = @"<\s*option[^>]*>(?<valeur>([^<]*))</option>";
            Regex regex = new Regex(ex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            var resultats = regex.Matches(webBrowser.Url.ToString());
            foreach (Match resultat in resultats)
            {
               MessageBox.Show(resultat.Value);
            }


C'est surement parce que dans source j'ai mis l'URL du site.
Est-ce possible en utilisant l'URL ?
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
37
Hello,

c'est clair que si tu donnes l'url à la regex, il y a peu de chance que ça fonctionne !
Il faut que tu récupères le flux html.


Sébastien FERRAND
Ingénieur Concepteur Senior
Microsoft Visual C# MVP 2004 - 2009
Blog Photo
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
49
Comme dit Sebmafate, tu risques pas de trouver des balises <option> dans une url.

Utilise webBrowser.DocumentText

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

Merci pour vos réponses,

lorsqie j'utilise webBrowser.DocumentText

j'obtiens <option value="x"> Texte 1 </option>
et non pas "Texte 1"

De plus je viens de m'apercevoir que la balise option est utilisé a d'autre endroit de la page web.
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
37
pour récupérer la valeur il faut prendre le groupe nommée "valeur".




Sébastien FERRAND
Ingénieur Concepteur Senior
Microsoft Visual C# MVP 2004 - 2009
Blog Photo
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

Comment le fait - on ?
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
49
resultat.Groups["valeur"].Value

En gros, "resultat" correspond à du texte qui correspond à ta regex (en l'occurrence, qui commence par "<option" et finit par "</option>").
Il est donc normal que tu récupères la ligne entière.

Mais si tu regardes dans la regex, tu vois "(?<valeur>([^<]*))", ce qui signifie qu'on prend tous les caractères jusqu'au "<" suivant, et qu'on nomme ce groupe de caractères "valeur".

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

ça fonctionne, parfait.
Merci beaucoup !!!
je découvre juste comment fonctionne les expressions régulières.

Une idée de comment faire pour ciblé quel tableau je veux sélectionné afin d'avoir le contenu des balise option ?
et de comment supprimer les   ?
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
49
Pour supprimer les il suffit de les remplacer par rien (ou par un espace, comme tu veux) :

monNouveauTexte = monTexte.Replace(" ", "");


Pour cibler un tableau bien précis, on peut par exemple filtrer la zone du texte via une autre expression régulière :

string monTextePrecis = "Aller à:";
string ex = @"]*>[^&#164;]*]*>" + monTextePrecis + @"[^&#164;]*
";
// Oui, je sais, mon expression est vraiment pas propre, mais elle marche.
// PS : Si quelqu'un se rappelle comment on dit n'importe quel nombre 
// de n'importe quel signe (parce que s'il y a un symbole devant, 
// * ne marchera que pour ce symbole), je suis prenneur
Regex regex = new Regex(ex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
Match resultat = regex.Match(source);
regex = new Regex(@"<\s*option[^>]*>(?<valeur>([^<]*))</option>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
MatchCollection resultats = regex.Matches(resultat.Value);
foreach (Match resultat2 in resultats)
{
    Console.WriteLine(resultat2.Groups["valeur"].Value);
}


Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
37
Juste une petite remarque :

l'expression : <table[^>]*>
peut s'écrire <table.*?>

:)

par contre, je ne comprends pas ton problème :
// PS : Si quelqu'un se rappelle comment on dit n'importe quel nombre
// de n'importe quel signe (parce que s'il y a un symbole devant,
// * ne marchera que pour ce symbole), je suis prenneur



Sébastien FERRAND
Ingénieur Concepteur Senior
Microsoft Visual C# MVP 2004 - 2009
Blog Photo
Messages postés
18
Date d'inscription
mardi 20 décembre 2005
Statut
Membre
Dernière intervention
31 janvier 2012

Merci pour ces infos, par contre pour la 2ème partie j'ai tester ce code et il ne met que des message d'erreur.


string monTextePrecis = "Aller à:";
            string ex = @"]*>[^&#164;]*]*>" + monTextePrecis + @"[^&#164;]*
";
            // Oui, je sais, mon expression est vraiment pas propre, mais elle marche.
            // PS : Si quelqu'un se rappelle comment on dit n'importe quel nombre 
            // de n'importe quel signe (parce que s'il y a un symbole devant, 
            // * ne marchera que pour ce symbole), je suis prenneur
            Regex regex = new Regex(ex, RegexOptions.Compiled | RegexOptions.IgnoreCase);
            Match resultat = regex.Match(webBrowser.DocumentText);
            regex = new Regex(@"<\s*option[^>]*>(?<valeur>([^<]*))</option>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            MatchCollection resultats = regex.Matches(resultat.Value);
            foreach (Match resultat2 in resultats)
            {
                Console.WriteLine(resultat2.Groups["valeur"].Value);
            }
Messages postés
1860
Date d'inscription
lundi 28 novembre 2005
Statut
Modérateur
Dernière intervention
14 février 2015
49
@miminooze : Ne penses-tu pas qu'indiquer les messages d'erreur que tu rencontres pourrait-être une bonne idée ?

@sebmafate : Pour mon problème : par exemple, comment faire une regex pour un texte qui commence par "salut", suivi d'absolument n'importe quoi, et qui se termine par "au revoir" ? Parce que à part en faisant un truc du genre "salut[^¤]*au revoir", je vois pas.

Krimog : while (!(succeed = try())) ;
- Nous ne sommes pas des décodeurs ambulants. Le style SMS est prohibé. -
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
37
@krimog :

c'est justement la correction que j'ai apporté à ta regex :

salut(.*?)au revoir




*? : Correspond zéro fois ou plus à l'élément précédent, mais le moins de fois possible.




Sébastien FERRAND
Ingénieur Concepteur Senior
Microsoft Visual C# MVP 2004 - 2009
Blog Photo
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
57