2009-06-14 4 views
125

Ist es möglich, den reinen HTML-Inhalt einer Webseite zu lesen, die in eine UIWebView geladen wurde?HTML-Inhalt von einem UIWebView lesen

Wenn nicht, gibt es eine andere Möglichkeit, HTML-Rohdaten von einer Webseite im iPhone SDK abzurufen (z. B. ein Äquivalent von .NET WebClient::openRead)?

Antwort

207

Die zweite Frage ist eigentlich einfacher zu beantworten. Sehen Sie sich die stringWithContentsOfURL:encoding:error:-Methode von NSString an - Sie können eine URL als Instanz von NSURL (die einfach aus NSString erstellt werden kann) übergeben und eine Zeichenfolge mit dem vollständigen Inhalt der Seite an diese URL zurückgeben. Zum Beispiel:

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

Nach diesem Code ausgeführt wird, googlePage wird das HTML für www.google.com enthalten und error wird alle Fehler in dem Abruf angetroffen enthalten. (Sie sollten den Inhalt von error nach dem Abruf überprüfen.)

Gehen Sie den anderen Weg (von einem UIWebView) ist ein bisschen schwieriger, aber ist im Grunde das gleiche Konzept. Sie verlassen nun die request aus der Sicht ziehen müssen, dann tun die Abruf- wie zuvor:

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

EDIT: Beide Methoden nehmen eine Leistung getroffen, jedoch, da sie die Anfrage zweimal tun. Sie können durch Greifen des Inhalts von einem aktuell geladenen UIWebView mit seiner stringByEvaluatingJavascriptFromString: Methode als solche dieses Problem umgehen:

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

Dadurch wird den aktuellen HTML-Inhalt der Ansicht mit dem Document Object Model, analysieren die JavaScript packen, dann geben Sie es als NSString * von HTML.

Eine andere Möglichkeit besteht darin, Ihre Anfrage zuerst programmgesteuert auszuführen und dann das UIWebView von dem, was Sie angefordert haben, zu laden. Nehmen wir an, Sie nehmen das zweite Beispiel oben, wo Sie NSString *page als Ergebnis eines Anrufs zu stringWithContentsOfURL:encoding:error: haben. Anschließend können Sie diese Zeichenfolge in die Web-Ansicht drücken loadHTMLString:baseURL: verwenden, vorausgesetzt, Sie auch auf die NSURL gehalten auf Sie angefordert:

[yourWebView loadHTMLString:page baseURL:requestURL]; 

Ich bin nicht sicher, aber wenn dies JavaScript in der Seite laufen Sie laden (Der Methodenname, loadHTMLString, ist etwas mehrdeutig, und die Dokumente sagen nicht viel darüber).

Für weitere Informationen:

+1

Awesome! Danke für die tolle Antwort. Ich vermute, dass beide Methoden dazu führen, dass die Seite zweimal geladen wird, was sich auf die Leistung auswirken kann. Gibt es eine Möglichkeit, das zu vermeiden? –

+2

In der Tat gibt es :) Bearbeitete Antwort. – Tim

+1

Ja, [yourWebView loadHTMLString: page baseURL: requestURL]; wird das Javascript auf der Seite ausführen. Ich habe diese API mit Google Maps verwendet. – jeff7091

88

wenn Sie den Inhalt eines bereits geladenen UIWebView extrahieren möchten, - stringByEvaluatingJavaScriptFromString.Zum Beispiel:

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

Verdammt, das ist schlau! – jemmons

+2

Die Frage, die ich habe, ist, was passiert, wenn der Inhalt zufällig eine JSON-Zeichenfolge oder gar eine rohe Zeichenfolge ohne Body-Tag ist? – stephenmuss

+0

Dies ist keine gesunde Lösung! Alle JavaScript-Code und Header-Informationen sind auf diese Weise verloren. –

19

zu lesen: -

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

zu ändern: -

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

Beachten Sie, dass der NSString stringWithContentsOfURL einen ganz anderen User-Agenten-String als die UIWebView Herstellung berichten die gleiche Anfrage. Wenn Ihr Server also User-Agent-fähig ist und unterschiedliche HTML-Dateien zurücksendet, je nachdem, wer danach fragt, erhalten Sie auf diese Weise möglicherweise keine korrekten Ergebnisse.

Beachten Sie auch, dass das oben erwähnte @"document.body.innerHTML" nur anzeigen, was in der body-Tag ist. Wenn Sie @"document.all[0].innerHTML" verwenden, erhalten Sie sowohl Kopf als auch Körper. Dies ist immer noch nicht der komplette Inhalt des UIWebView, da es nicht die Doctype oder HTML Tags zurückbekommt, aber es ist viel näher.

+0

Theoretisch * können * Sie den Doctype erhalten, indem Sie ihn vom Server anfordern. Es ist wahrscheinlich, dass sich der Doctype nicht basierend auf Useragent ändert. – Moshe

40

Um die gesamten HTML-Rohdaten (mit <head> und <body>) zu erhalten:

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

Sie sollten dies versuchen:

document.documentElement.outerHTML

0

In Swif t v3:

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

Ich benutze eine rasche Erweiterung wie folgt aus:

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

}