Lettura di contenuti HTML da un UIWebView


132

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

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

Risposte:


216

La seconda domanda è in realtà più facile a cui rispondere. Guarda il stringWithContentsOfURL:encoding:error:metodo di NSString: ti consente di passare un URL come istanza di NSURL (che può essere facilmente istanziato da NSString) e restituisce una stringa con il contenuto completo della pagina in 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 aver eseguito questo codice, googlePageconterrà l'HTML per www.google.com e errorconterrà eventuali errori riscontrati nel recupero. (Dovresti controllare il contenuto di errordopo il recupero.)

Andare dall'altra parte (da un UIWebView) è un po 'più complicato, ma fondamentalmente è lo stesso concetto. Dovrai estrarre la richiesta dalla vista, quindi eseguire il recupero come prima:

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

MODIFICA: Entrambi questi metodi subiscono un impatto sulle prestazioni, tuttavia, poiché fanno la richiesta due volte. Puoi aggirare questo problema afferrando il contenuto da un UIWebView attualmente caricato usando il suo stringByEvaluatingJavascriptFromString:metodo, come tale:

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

Ciò afferrerà il contenuto HTML corrente della vista utilizzando il Document Object Model, analizzerà JavaScript, quindi glielo fornirà come NSString * di HTML.

Un altro modo è fare prima la tua richiesta a livello di codice, quindi caricare UIWebView da quello che hai richiesto. Diciamo che prendi il secondo esempio sopra, dove hai NSString *pagecome risultato di una chiamata a stringWithContentsOfURL:encoding:error:. È quindi possibile inserire quella stringa nella visualizzazione Web utilizzando loadHTMLString:baseURL:, supponendo che si sia mantenuto anche nel NSURL richiesto:

[yourWebView loadHTMLString:page baseURL:requestURL];

Non sono sicuro, tuttavia, se questo eseguirà JavaScript trovato nella pagina caricata (il nome del metodo loadHTMLString, è alquanto ambiguo e i documenti non ne parlano molto).

Per maggiori informazioni:


1
Eccezionale! 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?
Fuzzy Purple Monkey,

2
È un dato di fatto, ci sono :) Risposta modificata.
Tim

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

3
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];è stato per me un salvavita diverse volte. Sembra tornare dal documento il più possibile.
ennalax,

2
@Hanuman Questo potrebbe aiutarti: NSString * head = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.head.innerHTML"]; NSString * body = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.body.innerHTML"]; NSString * totalPage = aggiungi entrambe le stringhe.
Deepukjayan,

91

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 è cosa succede se il contenuto sembra essere una stringa JSON o anche una stringa non elaborata senza un tag body?
Stephenmuss,

Questa non è una soluzione salutare! Tutto il codice javascript e le informazioni dell'intestazione vanno persi in questo modo.
Radu Simionescu,

43

Per ottenere tutti i dati grezzi HTML (con <head>e <body>):

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

29

Si noti che la stringa NSStringWithContentsOfURL segnalerà una stringa agente utente totalmente diversa rispetto a UIWebView che effettua la stessa richiesta. Quindi, se il tuo server è a conoscenza dell'agente utente e restituisce HTML diversi a seconda di chi lo richiede, potresti non ottenere risultati corretti in questo modo.

Si noti inoltre che quanto @"document.body.innerHTML"sopra indicato mostrerà solo ciò che è nel tag body. Se usi @"document.all[0].innerHTML"otterrai sia la testa che il corpo. Che non è ancora il contenuto completo di UIWebView, poiché non ripristinerà i tag! Doctype o html, ma è molto più vicino.


In teoria, si potrebbe ottenere il doctype richiedendo dal server. È probabile che il tipo di documento non cambi in base all'agente utente.
Moshe,

20

Leggere:-

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

Modificare:-

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

2

In Swift v3:

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


1

Uso un'estensione rapida come questa:

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

}

1

dovresti provare questo:

document.documentElement.outerHTML

1

UIWebView

ottenere HTML da UIWebView`

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

imposta 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
}

[ottieni / imposta HTML da WKWebView]

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.