Récupérer un élément particulier d'une page HTML

orfaitorfait Membre
septembre 2007 modifié dans API AppKit #1
Bonjour,

je suis depuis quelques temps en train de chercher à  récupérer le contenu de la balise <title> d'une page web. J'ai trouvé un exemple fourni par Apple qui parvient à  faire un listing des balises mais le code est très obscur... (DOMTreeView).

Donc si quelqu'un a une réponse, un exemple, une voie de recherche, je suis preneur.
Si je trouve, je mettrai ma réponse ici.


Merci !


EDIT : précision très importante : je souhaite faire ceci sans utiliser de WebView et j'ai vu sur les list apple : "WebKit does not support loading viewless data sources.". Je pense que ma question a plus de sens avec ce détail.

Réponses

  • Philippe49Philippe49 Membre
    20:29 modifié #2
    dans 1190549109:

    Bonjour,

    je suis depuis quelques temps en train de chercher à  récupérer le contenu de la balise <title> d'une page web. J'ai trouvé un exemple fourni par Apple qui parvient à  faire un listing des balises mais le code est très obscur... (DOMTreeView).

    Donc si quelqu'un a une réponse, un exemple, une voie de recherche, je suis preneur.
    Si je trouve, je mettrai ma réponse ici.


    Merci !


    Si ton document est compliqué, voir le tuto sur XML.
    sinon le faire à  la main par manip de chaà®ne ne devrait pas être compliqué à  partir du source de la page HTML.
  • Philippe49Philippe49 Membre
    septembre 2007 modifié #3
    dans 1190549109:
    !


    EDIT : précision très importante : je souhaite faire ceci sans utiliser de WebView et j'ai vu sur les list apple : "WebKit does not support loading viewless data sources.". Je pense que ma question a plus de sens avec ce détail.


    désolé, j'avais pas lu, ma réponse est à  côté.

    mais en même comme tu parles d'un exemple fourni par Apple réalisant une arborescence à  partir de la page Web, il y a un peu contradiction ...
  • orfaitorfait Membre
    20:29 modifié #4
    Mais tu avais cité mon message de départ et il n'y a pas mon "EDIT", donc aucune ambiguà¯té.
    Ton lien m'a beaucoup intéressé mais je crois que ce n'est pas adapté... enfin, je lis car il n'y a pas qu'une seule page  :)

    En revanche, je crois que je n'ai pas le choix que d'utiliser un WebView (masqué) si je veux rester avec le webkit.
  • BruBru Membre
    20:29 modifié #5
    dans 1190561910:

    En revanche, je crois que je n'ai pas le choix que d'utiliser un WebView (masqué) si je veux rester avec le webkit.


    Tu as toujours le choix.
    Mais, en passant par le webkit, tu fais faire une bonne partie du travail par ce framework (récupérer le contenu de la balise <TITLE> du doc html n'est pas toujours suffisant : imagine que ce titre soit mis par javascript...).

    Effectivement, un petit webview non affiché est suffisant.
    Par exemple, tu peux mettre ce webview dans un nib tout seul.
    Ensuite, tu charges le nib (et donc instancie le webview), puis tu utilises le webview pour charger la page et puis lire son titre. Enfin tu peux décharger le nib.

    Voici un exemple (l'outlet du webview se nome wb).

    Il faut charger la page :
    <br />{<br />&nbsp; &nbsp;// chargement du site objective-cocoa.org<br />&nbsp; &nbsp;[[wb mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@&quot;http://www.objective-cocoa.org/forum/index.php&quot;]]];<br />}<br />
    


    Ensuite, il faut utiliser une méthode delegate qui se déclenche quand la page a fini d'être chargée :
    <br />- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame<br />{<br />&nbsp; &nbsp; DOMDocument *docHtml;<br />&nbsp; &nbsp; NSString *title;<br /><br />&nbsp; &nbsp; // récupération du contenu html (au format DOM)<br />&nbsp; &nbsp; docHtml=[frame DOMDocument];<br /><br />&nbsp; &nbsp; // récupération du titre du document<br />&nbsp; &nbsp; title=[docHtml title];<br /><br />&nbsp; &nbsp; // titre récupéré !<br />&nbsp; &nbsp; NSLog(@&quot;%@&quot;, title);<br />}<br />
    


    (il faut connecter le delegate FrameLoadDelegate à  l'objet contrôleur).

    .
  • elfelf Membre
    20:29 modifié #6
    dans 1190549109:

    Bonjour,

    je suis depuis quelques temps en train de chercher à  récupérer le contenu de la balise <title> d'une page web. J'ai trouvé un exemple fourni par Apple qui parvient à  faire un listing des balises mais le code est très obscur... (DOMTreeView).

    Donc si quelqu'un a une réponse, un exemple, une voie de recherche, je suis preneur.
    Si je trouve, je mettrai ma réponse ici.


    Merci !


    EDIT : précision très importante : je souhaite faire ceci sans utiliser de WebView et j'ai vu sur les list apple : "WebKit does not support loading viewless data sources.". Je pense que ma question a plus de sens avec ce détail.


    Bah le plus simple (mais p-ê pas le plus propre) c'est de faire une regex... C'est ce que je fais, pas besoin de resortire tout l'apareil XML compliquer...
  • BruBru Membre
    20:29 modifié #7
    dans 1190758800:

    Bah le plus simple (mais p-ê pas le plus propre) c'est de faire une regex... C'est ce que je fais, pas besoin de resortire tout l'apareil XML compliquer...


    Voici une page html :
    [tt]
    <html>
      <head>
          <script language="javascript">var unTitre='joli titre';</script>
          <style>
            body { background-color: yellow; }
          </style>
      </head>
      <body onload="javascript:document.title=unTitre">
          bla bla
      </body>
    </html>
    [/tt]
    Tu fais comment avec ton regex pour récupérer le titre ?

    .
  • Philippe49Philippe49 Membre
    septembre 2007 modifié #8
    dans 1190758800:

    C'est ce que je fais, pas besoin de resortire tout l'apareil XML compliquer...


    Bah en même temps XML est simple, sauf si le titre est masqué dans le doc comme le montre l'exemple de Bru :

    #import <Cocoa/Cocoa.h>
     
    int main(int argc, char * argv[] ){
        NSAutoreleasePool * pool=[NSAutoreleasePool new];
        NSError * error;
        // création du document
        NSString * xmlString=[NSString stringWithUTF8String:
    "<html>  \
    <head>\
    <script language='javascript'>var unTitre='joli titre';</script> \
    <style> \
    body { background-color: yellow; }\
    </style>\
    </head>\
    <body onload=\"javascript:document.title=unTitre\">\
    bla bla\
    </body>\
    </html> "];
        NSXMLDocument * xmlDoc;
    xmlDoc=[[NSXMLDocument alloc] initWithXMLString:xmlString
    options:NSXMLNodePreserveWhitespace|NSXMLNodePreserveCDATA
    error:&error];

        // lecture de ce que l'on veut : par exemple le style
        NSArray * nodes;
        nodes=[[xmlDoc rootElement] nodesForXPath:@//style/text() error:&error];
        if(error){
            NSLog(@%@",error);
        }else{
            printf("%s\n",[[nodes description] UTF8String]);
        }
        [xmlDoc release];
    [pool release];
    return 0;
    }
  • elfelf Membre
    20:29 modifié #9
    dans 1190761499:

    dans 1190758800:

    Bah le plus simple (mais p-ê pas le plus propre) c'est de faire une regex... C'est ce que je fais, pas besoin de resortire tout l'apareil XML compliquer...


    Voici une page html :
    [tt]
    <html>
       <head>
          <script language="javascript">var unTitre='joli titre';</script>
          <style>
             body { background-color: yellow; }
          </style>
       </head>
       <body onload="javascript:document.title=unTitre">
          bla bla
       </body>
    </html>
    [/tt]
    Tu fais comment avec ton regex pour récupérer le titre ?

    .


    /<html>.*<body onload="javascript:document.title=(.*)">.*/ $1
  • BruBru Membre
    20:29 modifié #10
    dans 1190811427:

    /<html>.*<body onload="javascript:document.title=(.*)">.*/ $1


    Biiiip, vous avez perdu... Recommencez encore une fois !

    (le regex va ramener le mot unTitre, qui est une variable javascript contenant elle même la valeur "joli titre").

    .
  • AliGatorAliGator Membre, Modérateur
    20:29 modifié #11
    dans 1190811427:

    /<html>.*<body onload="javascript:document.title=(.*)">.*/ $1
    Raté.

    D'une part ça ne marche pas tout à  fait parce que ça récupère "unTitre" qui est le nom d'une variable javascript et non pas une string litérale (d'ailleurs je soupçonne fort Bru d'avoir fait exprès de mettre ça comme page HTML en prévision que tu ferais l'erreur ^^)
    D'autre part parce que le but est de récupérer le titre de la page dans tous les cas imaginables. Par dans le cas particulier où il est dans <title> uniquement, et s'il est fixé en javascript il peut l'être de plein de manières différentes (le onload pouvant appeler une fonction javascript par exemple init(), et c'est dans le init() qu'en plein milieu on a un [tt]document.title = xxx[/tt], où xxx peut être une variable, un string litteral, ou même un appel de fonction, et que sait-je encore.

    bref tu ne pourras jamais prévoir tous les cas.
  • TchouboudouTchouboudou Membre
    20:29 modifié #12
    Ceci dit, mettre un titre avec du Javascript, c'est plutôt rare...
  • AliGatorAliGator Membre, Modérateur
    20:29 modifié #13
    Pas tant que ça, et encore moins avec ce que tout le monde se plait à  appeler le "Web 2.0" (mot qui veut rien dire mais bon), je pense en particulier à  des RIA utilisant AJAX par exemple, il suffit d'avoir un site avec un menu / une liste d'articles pour naviguer dedans, et qd on clique ça récupère l'article demandé en AJAX... et modifie le titre de la fenêtre pour y inclure le titre de l'article.

    Et puis la question n'est pas tant de savoir si ça n'est que 10 ou 15% des pages qui font ça ou pas, mais de prévoir tous les cas, non ?
    Et donc de préférer une solution qui donne le vrai titre en autant de lignes qu'une autre solution ne fonctionnant pas à  tous les coups.
    D'autant que Cocoa ne permet pas de faire des RegEx de base (bon ok un peu avec les NSPredicate, soyons honnêtes, mais bon), donc il faut pour bien faire rajouter un framework les gérant.
  • orfaitorfait Membre
    20:29 modifié #14
    Pour info, j'avais déjà  mis en oe“uvre une méthode similaire à  celle de Bru (merci Bru de m'avoir fait modifier avec un delegate... je n'y avais pas pensé).
    Mais je cherchais une solution très "simpliste" et sans devoir charger un "affichage" de page. Ceci dit, ma question serait plutôt de savoir si les ressources utilisées pour un webview masqué sont aussi "importantes" qu'avec un webview affiché.
    En fait, je me disais : "il doit sûrement exister un moyen pour éviter d'avoir à  "intepréter" le code HTML en vue d'un affichage... je ne veux avoir le contrôle que sur le code... inutile d'afficher."

    Voilà , je pense que la méthode indiquée par Bru est la bonne et je vais m'y tenir. J'espère que mon remue-ménage n'a pas dérangé... je ne pensais provoquer tant de réponses !
  • elfelf Membre
    20:29 modifié #15
    Erf ah ouais vous avez raison, j'avais pas fait gaffe quand j'ai lu le HTML...

    Bon si le unTitre est setté à  un endroit qui pourrait être n'importe ou, c'est vrai que c'est pas possible, mais c'est un cas rarisime... la plupart du temps, le titre est setté dans le HTML en utilisant <title> dans quel cas une regex suffit (/.*<head>.*<title>(.*)<.title>.*<.head>.*/) (c'est pas propre, mais ça fonctionne)

    Ce que je veux dire, c'est que dans la majorité des cas 99% du temps, il est inutile de faire 50 lignes de code XML quand une regex (3 lignes de code) suffit.

    Je suis sur que vous connaisez KISS?
Connectez-vous ou Inscrivez-vous pour répondre.