Lesen von HTML-Inhalten aus einer UIWebView


132

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

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

Antworten:


216

Die zweite Frage ist tatsächlich leichter zu beantworten. Schauen Sie sich die stringWithContentsOfURL:encoding:error:Methode von NSString an - Sie können eine URL als Instanz von NSURL übergeben (die leicht über NSString instanziiert werden kann) und eine Zeichenfolge mit dem vollständigen Inhalt der Seite unter dieser URL zurückgeben. Beispielsweise:

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

googlePageEnthält nach dem Ausführen dieses Codes den HTML- Code für www.google.com sowie erroralle beim Abrufen aufgetretenen Fehler. (Sie sollten den Inhalt errornach dem Abrufen überprüfen .)

Der andere Weg (von einer UIWebView aus) ist etwas schwieriger, aber im Grunde das gleiche Konzept. Sie müssen die Anforderung aus der Ansicht abrufen und dann wie zuvor abrufen:

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

BEARBEITEN: Beide Methoden haben jedoch einen Leistungseinbruch, da sie die Anforderung zweimal ausführen. Sie können dies umgehen, indem Sie den Inhalt aus einer aktuell geladenen UIWebView mithilfe der folgenden stringByEvaluatingJavascriptFromString:Methode abrufen :

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

Dadurch wird der aktuelle HTML-Inhalt der Ansicht mithilfe des Dokumentobjektmodells abgerufen, das JavaScript analysiert und als NSString * von HTML angezeigt.

Eine andere Möglichkeit besteht darin, Ihre Anfrage zuerst programmgesteuert zu bearbeiten und dann die UIWebView von der von Ihnen angeforderten zu laden. Nehmen wir an, Sie nehmen das zweite Beispiel oben, in dem Sie NSString *pageals Ergebnis eines Anrufs bei haben stringWithContentsOfURL:encoding:error:. Sie können diese Zeichenfolge dann mithilfe loadHTMLString:baseURL:von in die Webansicht verschieben, vorausgesetzt, Sie haben auch an der von Ihnen angeforderten NSURL festgehalten:

[yourWebView loadHTMLString:page baseURL:requestURL];

Ich bin mir jedoch nicht sicher, ob hier JavaScript ausgeführt wird, das auf der von Ihnen geladenen Seite gefunden wurde (der Methodenname loadHTMLStringist etwas mehrdeutig, und die Dokumente sagen nicht viel darüber aus).

Für mehr Information:


1
Genial! Danke für die tolle Antwort. Ich gehe davon aus, dass beide Methoden dazu führen, dass die Seite zweimal geladen wird, was sich auf die Leistung auswirken kann. Gibt es eine Möglichkeit, dies zu vermeiden?
Fuzzy Purple Monkey

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

1
Ja, [yourWebView loadHTMLString: page baseURL: requestURL]; führt das Javascript auf der Seite aus. Ich habe diese API mit Google Maps verwendet.
Jeff7091

3
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];war schon mehrmals ein Lebensretter für mich. Es scheint so weit wie möglich aus dem Dokument zurückzukehren.
Ennalax

2
@Hanuman Dies könnte Ihnen helfen: NSString * head = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.head.innerHTML"]; NSString * body = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.body.innerHTML"]; NSString * totalPage = beide Zeichenfolgen anhängen.
Deepukjayan

91

Wenn Sie den Inhalt einer bereits geladenen UIWebView extrahieren möchten, verwenden Sie -stringByEvaluatingJavaScriptFromString. Beispielsweise:

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

10
Verdammt, das ist klug!
Jemmons

2
Die Frage, die ich habe, ist, was passiert, wenn der Inhalt eine JSON-Zeichenfolge oder sogar eine Rohzeichenfolge ohne Body-Tag ist?
Stephenmuss

Dies ist keine gesunde Lösung! Der gesamte Javascript-Code und die Header-Informationen gehen auf diese Weise verloren.
Radu Simionescu

43

So erhalten Sie die gesamten HTML-Rohdaten (mit <head>und <body>):

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

29

Beachten Sie, dass der NSString stringWithContentsOfURL eine völlig andere Benutzeragentenzeichenfolge meldet als der UIWebView, der dieselbe Anforderung stellt. Wenn Ihr Server also User-Agent-fähig ist und je nachdem, wer danach fragt, unterschiedliche HTML-Dateien zurücksendet, erhalten Sie auf diese Weise möglicherweise keine korrekten Ergebnisse.

Beachten Sie auch, dass @"document.body.innerHTML"oben nur das angezeigt wird, was sich im Body-Tag befindet. Wenn Sie verwenden, erhalten @"document.all[0].innerHTML"Sie sowohl Kopf als auch Körper. Dies ist immer noch nicht der vollständige Inhalt von UIWebView, da die Tags! Doctype oder html nicht zurückgegeben werden, aber es ist viel näher.


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

20

Lesen:-

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

Ändern:-

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

2

In Swift v3:

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


1

Ich benutze eine schnelle Erweiterung wie diese:

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

}

1

Sie sollten dies versuchen:

document.documentElement.outerHTML

1

UIWebView

Holen Sie sich HTML von UIWebView`

let content = uiWebView.stringByEvaluatingJavaScript(from: "document.body.innerHTML")

Setzen Sie HTML in UIWebView

//Do not forget to extend a class from `UIWebViewDelegate` and nil the delegate

func someFunction() {

    let uiWebView = UIWebView()
    uiWebView.loadHTMLString("<html><body></body></html>", baseURL: nil)
    uiWebView.delegate = self as? UIWebViewDelegate
}

func webViewDidFinishLoad(_ webView: UIWebView) {
    //ready to be processed
}

[HTML von WKWebView abrufen / festlegen]

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.