2009-06-14 6 views
125

Est-il possible de lire le contenu HTML brut d'une page Web qui a été chargée dans un UIWebView? Si ce n'est pas le cas, existe-t-il un autre moyen de récupérer du contenu HTML brut à partir d'une page Web du SDK iPhone (tel qu'un équivalent du .NET WebClient::openRead)?Lecture de contenu HTML à partir d'un UIWebView

Répondre

207

La deuxième question est réellement plus facile de répondre. Regardez la méthode stringWithContentsOfURL:encoding:error: de NSString - elle vous permet de passer une URL en tant qu'instance de NSURL (qui peut facilement être instanciée à partir de NSString) et renvoie une chaîne avec le contenu complet de la page à cette URL. Par exemple:

NSString *googleString = @"http://www.google.com"; 
NSURL *googleURL = [NSURL URLWithString:googleString]; 
NSError *error; 
NSString *googlePage = [NSString stringWithContentsOfURL:googleURL 
               encoding:NSASCIIStringEncoding 
                error:&error]; 

Après l'exécution de ce code, googlePage contiendra le code HTML pour www.google.com et error contiendra toutes les erreurs rencontrées dans la récupération. (Vous devriez vérifier le contenu de error après l'extraction.)

Aller dans l'autre sens (à partir d'un UIWebView) est un peu plus compliqué, mais c'est fondamentalement le même concept. Vous devrez tirer le request de la vue, puis le rechercher comme avant:

NSURL *requestURL = [[yourWebView request] URL]; 
NSError *error; 
NSString *page = [NSString stringWithContentsOfURL:requestURL 
              encoding:NSASCIIStringEncoding 
              error:&error]; 

EDIT: Ces deux méthodes prennent un coup de performance, cependant, car ils font la demande deux fois. Vous pouvez contourner ce problème en saisissant le contenu d'un UIWebView actuellement chargé à l'aide de sa méthode stringByEvaluatingJavascriptFromString:, comme tel:

NSString *html = [yourWebView stringByEvaluatingJavaScriptFromString: 
             @"document.body.innerHTML"]; 

Cela va récupérer le contenu actuel HTML de l'affichage à l'aide du modèle objet de document, analyser le JavaScript, Puis donnez-le comme un NSString * de HTML.

Une autre méthode consiste à exécuter d'abord votre demande par programme, puis de charger UIWebView à partir de ce que vous avez demandé. Disons que vous prenez le deuxième exemple ci-dessus, où vous avez NSString *page à la suite d'un appel à stringWithContentsOfURL:encoding:error:. Vous pouvez ensuite pousser cette chaîne dans la vue Web en utilisant loadHTMLString:baseURL:, en supposant que vous a également tenu à l'NSURL vous avez demandé:

[yourWebView loadHTMLString:page baseURL:requestURL]; 

Je ne suis pas sûr, cependant, si cela se déroulera du code JavaScript dans la page que vous chargez (le nom de la méthode, loadHTMLString, est quelque peu ambigu, et les docs n'en parlent pas beaucoup).

Pour plus d'informations:

+1

Impressionnant! Merci pour la bonne réponse. Je suppose que les deux méthodes entraînent le chargement de la page deux fois, ce qui peut avoir un impact sur les performances. Y a-t-il un moyen d'éviter cela? –

+2

En fait, il y a :) réponse éditée. – Tim

+1

Oui, [votreWebHow loadHTMLString: page baseURL: requestURL]; va exécuter le Javascript dans la page. J'ai utilisé cette API avec Google Maps. – jeff7091

88

si vous voulez extraire le contenu d'un UIWebView déjà chargé, - stringByEvaluatingJavaScriptFromString.Par exemple:

NSString *html = [webView stringByEvaluatingJavaScriptFromString: @"document.body.innerHTML"]; 
+10

Merde, c'est intelligent! – jemmons

+2

La question que j'ai est ce qui se passe si le contenu se trouve être une chaîne JSON ou même une chaîne brute sans balise body? – stephenmuss

+0

Ce n'est pas une solution saine! Tout le code javascript et les informations d'en-tête sont perdus de cette façon. –

19

A lire: -

NSString *html = [myWebView stringByEvaluatingJavaScriptFromString: @"document.getElementById('your div id').textContent"]; 
NSLog(html);  

Pour modifier: -

html = [myWebView stringByEvaluatingJavaScriptFromString: @"document.getElementById('your div id').textContent=''"]; 
29

Notez que le NSString stringWithContentsOfURL rapportera un tout autre chaîne de l'agent utilisateur que la fabrication UIWebView la même requête. Donc, si votre serveur est conscient de l'utilisation de l'agent, et que vous renvoyez un code html différent selon la personne qui le demande, vous risquez de ne pas obtenir les résultats corrects de cette façon.

Notez également que le @"document.body.innerHTML" mentionné ci-dessus n'affichera que ce qui est dans l'étiquette du corps. Si vous utilisez @"document.all[0].innerHTML" vous obtiendrez à la fois la tête et le corps. Ce qui n'est pas encore le contenu complet de l'UIWebView, puisqu'il ne récupérera pas les balises! Doctype ou html, mais c'est beaucoup plus proche.

+0

Théoriquement, vous pouvez * obtenir * le doctype en le demandant au serveur. Il est probable que le doctype ne changera pas en fonction de useragent. – Moshe

40

Pour obtenir l'ensemble des données brutes HTML (avec <head> et <body>):

NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"]; 
1

essayez ceci:

document.documentElement.outerHTML

0

En Swif t v3:

let doc = webView.stringByEvaluatingJavaScript(from: "document.documentElement.outerHTML") 
0

J'utilise une extension rapide comme ceci:

extension UIWebView { 
    var htmlContent:String? { 
     return self.stringByEvaluatingJavaScript(from: "document.documentElement.outerHTML") 
    } 

} 
Questions connexes