Comment faire afficher le titre d'une page HTML dans UIWebView?


145

J'ai besoin d'extraire le contenu de la balise de titre d'une page HTML affichée dans une UIWebView. Quel est le moyen le plus robuste de le faire?

Je sais que je peux faire:

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSString *theTitle=[webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}

Cependant, cela ne fonctionne que si javascript est activé.

Sinon, je pourrais simplement scanner le texte du code HTML pour le titre, mais cela semble un peu fastidieux et pourrait s'avérer fragile si les auteurs de la page devenaient bizarres avec leur code. Dans ce cas, quelle est la meilleure méthode à utiliser pour traiter le texte html dans l'API iPhone?

J'ai l'impression d'avoir oublié quelque chose d'évident. Existe-t-il une meilleure méthode que ces deux choix?

Mettre à jour:

Suite de la réponse à cette question: UIWebView: Pouvez-vous désactiver Javascript? il ne semble y avoir aucun moyen de désactiver Javascript dans UIWebView. Par conséquent, la méthode Javascript ci-dessus fonctionnera toujours.


1
+1 J'ai également dû recourir à la méthode @ "document.title".
Dave DeLong

J'étais juste à la recherche de cela et j'avais des visions effrayantes de l'analyse du HTML. Solution très intelligente.
margusholland

Voir aussi la réponse suivante à une question similaire de SO: stackoverflow.com/a/2313430/908621
fishinear le


La communauté d'assistance Apple a également la même réponse
Daniel

Réponses:


88

Pour ceux qui font défiler vers le bas pour trouver la réponse:

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSString *theTitle=[webView stringByEvaluatingJavaScriptFromString:@"document.title"];
}

Cela fonctionnera toujours car il n'y a aucun moyen de désactiver Javascript dans UIWebView.


en utilisant ceci, si le codage de la page Web n'est pas «utf-8», le titre serait désordonné.
Xiao

Et pour Swift 4?
Jayprakash Dubey

4

WKWebView a la propriété 'title', faites-le comme ça,

func webView(_ wv: WKWebView, didFinish navigation: WKNavigation!) {
    title = wv.title
}

Je ne pense pas que ce UIWebViewsoit approprié pour le moment.


3

Si Javascript activé, utilisez ceci: -

NSString *theTitle=[webViewstringByEvaluatingJavaScriptFromString:@"document.title"];

Si Javascript désactivé, utilisez ceci: -

NSString * htmlCode = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.appcoda.com"] encoding:NSASCIIStringEncoding error:nil];
NSString * start = @"<title>";
NSRange range1 = [htmlCode rangeOfString:start];

NSString * end = @"</title>";
NSRange range2 = [htmlCode rangeOfString:end];

NSString * subString = [htmlCode substringWithRange:NSMakeRange(range1.location + 7, range2.location - range1.location - 7)];
NSLog(@"substring is %@",subString);

J'ai utilisé +7 et -7 dans NSMakeRange pour éliminer la longueur de <title>ie 7


Pouvez-vous désactiver Javascript dans UIWebview maintenant? En 2010, vous ne pouviez pas.
TechZen

Je ne sais pas sur IOS avant IOS 8 mais vous pouvez le faire, allez dans Paramètres -> Safari -> Avancé -> Javascript
activé

Comment savoir si javascript est activé ou désactivé dans le code?
Eddie

2

Edit: je viens de voir que vous avez trouvé la réponse ... sheeeiiitttt

Je viens de l'apprendre littéralement! Pour ce faire, vous n'avez même pas besoin de l'afficher dans UIWebView. (Mais comme vous l'utilisez, vous pouvez simplement obtenir l'URL de la page actuelle)

Quoi qu'il en soit, voici le code et quelques (faibles) explications:

    //create a URL which for the site you want to get the info from.. just replace google with whatever you want
    NSURL *currentURL = [NSURL URLWithString:@"http://www.google.com"];
    //for any exceptions/errors
    NSError *error;
    //converts the url html to a string
    NSString *htmlCode = [NSString stringWithContentsOfURL:currentURL encoding:NSASCIIStringEncoding error:&error];

Nous avons donc le code HTML, maintenant comment obtenir le titre? Eh bien, dans chaque document basé sur html, le titre est signalé par This Is the Title. Donc, la chose la plus simple à faire est probablement de rechercher cette chaîne htmlCode pour, et pour, et de la sous-traiter afin que nous obtenions les choses entre les deux.

    //so let's create two strings that are our starting and ending signs
    NSString *startPoint = @"<title>";
    NSString *endPoint = @"</title>";
    //now in substringing in obj-c they're mostly based off of ranges, so we need to make some ranges
    NSRange startRange = [htmlCode rangeOfString:startPoint];
    NSRange endRange = [htmlCode rangeOfString:endPoint];
    //so what this is doing is it is finding the location in the html code and turning it
    //into two ints: the location and the length of the string
    //once we have this, we can do the substringing!
    //so just for easiness, let's make another string to have the title in
    NSString *docTitle = [htmlString substringWithRange:NSMakeRange(startRange.location + startRange.length, endRange.location)];
    NSLog(@"%@", docTitle);
    //just to print it out and see it's right

Et c'est vraiment ça! Donc, fondamentalement, pour expliquer toutes les manigances qui se produisent dans le docTitle, si nous avons créé une plage simplement en disant NSMakeRange (startRange.location, endRange.location), nous obtiendrions le titre ET le texte de startString (ce qui est) parce que l'emplacement est par le premier caractère de la chaîne. Donc, pour compenser cela, nous avons simplement ajouté la longueur de la chaîne

Maintenant, gardez à l'esprit que ce code n'est pas testé ... s'il y a des problèmes, cela peut être une faute d'orthographe, ou que je n'ai pas / ai ajouté un pointeur alors que je n'étais pas censé le faire.

Si le titre est un peu bizarre et pas tout à fait correct, essayez de jouer avec le NSMakeRange - je veux dire comme ajouter / soustraire différentes longueurs / emplacements des chaînes - tout ce qui semble logique.

Si vous avez des questions ou si vous rencontrez des problèmes, n'hésitez pas à les poser. C'est ma première réponse sur ce site, donc désolé si c'est un peu désorganisé


1

Voici la version Swift 4, basée sur la réponse ici

func webViewDidFinishLoad(_ webView: UIWebView) {
    let theTitle = webView.stringByEvaluatingJavaScript(from: "document.title")
}

0

Je n'ai pas d'expérience avec les vues Web jusqu'à présent, mais je pense que cela définit son titre sur le titre de la page, donc, une astuce que je suggère est d'utiliser une catégorie sur la vue Web et d'écraser le setter pour self.title afin d'ajouter un message à l'un de vous s'oppose ou modifie une propriété pour obtenir le titre.

Pouvez-vous essayer de me dire si cela fonctionne?


0

Si vous en avez besoin fréquemment dans votre code, je vous suggère d'ajouter une fonction dans "extension UIWebView" comme ceci

extension UIWebView {

func title() -> String{
    let title: String = self.stringByEvaluatingJavaScript(from: "document.title")!
    return title
}

sinon, il est préférable d'utiliser WKWebView.

Malheureusement, ce n'est pas bien pris en charge dans ARKit. J'ai dû abandonner WKWebView. Je n'ai pas pu charger le site Web dans la vue Web. Si quelqu'un a une solution à ce problème ici -> j'ai un problème similaire, cela aiderait grandement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.