2009-06-14 19 views
125

È possibile leggere il contenuto HTML non elaborato di una pagina Web che è stata caricata in un UIWebView?Lettura di contenuto HTML da una UIWebView

In caso contrario, c'è un altro modo per estrarre il contenuto HTML non elaborato da una pagina Web nell'SDK di iPhone (ad esempio un equivalente di .NET WebClient::openRead)?

risposta

207

La seconda domanda è in realtà più facile da rispondere. Guarda il metodo stringWithContentsOfURL:encoding:error: di NSString: ti consente di passare un URL come un'istanza di NSURL (che può essere facilmente istanziata da NSString) e restituisce una stringa con il contenuto completo della pagina su quell'URL. Per esempio:

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

Dopo l'esecuzione di questo codice, googlePage conterrà il codice HTML per www.google.com, e error conterrà eventuali errori riscontrati nel recupero. (Si dovrebbe verificare il contenuto del error dopo il recupero.)

Andando nella direzione opposta (da un UIWebView) è un po 'più complicato, ma è fondamentalmente lo stesso concetto. Dovrete tirare la request dalla vista, poi fare la prendere come prima:

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

EDIT: Entrambi questi metodi prendono un calo di prestazioni, tuttavia, dal momento che fanno la richiesta per due volte. È possibile aggirare questo afferrando il contenuto da un UIWebView attualmente caricata utilizzando il suo metodo stringByEvaluatingJavascriptFromString:, come ad esempio:

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

Ciò afferrare il contenuto HTML corrente della vista utilizzando il Document Object Model, analizzare il codice JavaScript, quindi dartelo come NSString * di HTML.

Un altro modo è di eseguire prima la richiesta in modo programmatico, quindi caricare UIWebView da ciò che è stato richiesto. Supponiamo che tu prenda il secondo esempio sopra, dove hai NSString *page come risultato di una chiamata a stringWithContentsOfURL:encoding:error:. È quindi possibile spingere quella stringa nella visualizzazione Web utilizzando loadHTMLString:baseURL:, supponendo che si tengono anche al NSURL richiesto:

[yourWebView loadHTMLString:page baseURL:requestURL]; 

Non sono sicuro, però, se questo verrà eseguito JavaScript trovato nella pagina si carica (il nome del metodo, loadHTMLString, è un po 'ambiguo, e i documenti non dicono molto a riguardo).

Per maggiori informazioni:

+1

Impressionante! Grazie per la magnifica risposta. Presumo che entrambi i metodi comportino il caricamento della pagina due volte, il che potrebbe avere un impatto sulle prestazioni. C'è un modo per evitarlo? –

+2

In effetti, ci sono :) Risposta modificata. – Tim

+1

Sì, [yourWebView loadHTMLString: page baseURL: requestURL]; eseguirà il Javascript nella pagina. Ho usato questa API con le mappe di Google. – jeff7091

88

se si desidera estrarre il contenuto di un UIWebView già caricato, - stringByEvaluatingJavaScriptFromString.Per esempio:

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

Accidenti, è intelligente! – jemmons

+2

La domanda che ho è che cosa succede se il contenuto sembra essere una stringa JSON o anche una stringa raw senza un body tag? – stephenmuss

+0

Questa non è una soluzione salutare! Tutto il codice javascript e le informazioni dell'intestazione sono persi in questo modo. –

19

Per leggere: -

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

Per modificare: -

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

Nota che il NSString stringWithContentsOfURL riporterà una stringa user-agent del tutto diverso da quello che si UIWebView la stessa richiesta Quindi, se il tuo server è consapevole di user-agent, e inviando diversi html a seconda di chi lo sta chiedendo, potresti non ottenere risultati corretti in questo modo.

Si noti inoltre che lo @"document.body.innerHTML" menzionato sopra visualizzerà solo ciò che si trova nel tag del corpo. Se usi @"document.all[0].innerHTML" otterrai sia la testa che il corpo. Quale non è ancora il contenuto completo di UIWebView, dal momento che non recupererà i tag doctype o html, ma è molto più vicino.

+0

In teoria, * potresti * ottenere il doctype richiedendolo dal server. È probabile che il doctype non cambi in base a useragent. – Moshe

40

per ottenere l'intera HTML dati grezzi (con <head> e <body>):

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

si dovrebbe provare questo:

document.documentElement.outerHTML

0

In Swif t v3:

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

utilizzo un'estensione rapida come questo:

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

} 
Problemi correlati