Lendo conteúdo HTML de um UIWebView

132

É possível ler o conteúdo HTML bruto de uma página da Web que foi carregada em um UIWebView?

Caso contrário, existe outra maneira de extrair conteúdo HTML bruto de uma página da Web no iPhone SDK (como um equivalente do .NET WebClient::openRead)?

Macaco roxo distorcido
fonte

Respostas:

216

A segunda pergunta é realmente mais fácil de responder. Veja o stringWithContentsOfURL:encoding:error:método NSString - ele permite que você transmita um URL como uma instância do NSURL (que pode ser facilmente instanciada pelo NSString) e retorna uma string com o conteúdo completo da página nesse URL. Por exemplo:

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

Após a execução desse código, googlePageo HTML errorserá www.google.com e os erros encontrados na busca. (Você deve verificar o conteúdo errorapós a busca.)

Indo para o outro lado (a partir de um UIWebView) é um pouco mais complicado, mas é basicamente o mesmo conceito. Você precisará extrair a solicitação da visualização e fazer a busca como antes:

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

EDIT: No entanto, esses dois métodos sofrem um impacto no desempenho, pois fazem a solicitação duas vezes. Você pode contornar isso capturando o conteúdo de um UIWebView carregado no momento usando seu stringByEvaluatingJavascriptFromString:método, como:

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

Isso irá capturar o conteúdo HTML atual da visualização usando o Document Object Model, analisar o JavaScript e fornecer a você como um NSString * de HTML.

Outra maneira é fazer sua solicitação programaticamente primeiro e carregar o UIWebView a partir do que você solicitou. Digamos que você pegue o segundo exemplo acima, onde está NSString *pageo resultado de uma chamada para stringWithContentsOfURL:encoding:error:. Em seguida, você pode enviar essa sequência para a visualização da Web usando loadHTMLString:baseURL:, assumindo que você também tenha mantido o NSURL solicitado:

[yourWebView loadHTMLString:page baseURL:requestURL];

No entanto, não tenho certeza se isso executará o JavaScript encontrado na página que você carrega (o nome do método loadHTMLString, é um tanto ambíguo e os documentos não dizem muito sobre isso).

Para mais informações:

Tim
fonte
1
Impressionante! Obrigado pela ótima resposta. Presumo que ambos os métodos resultem no carregamento da página duas vezes, o que pode ter um impacto no desempenho. Existe uma maneira de evitar isso?
Macaco Roxo Difuso
2
Por uma questão de fato, existem :) Resposta editada.
Tim
1
Sim, [yourWebView loadHTMLString: página baseURL: requestURL]; executará o Javascript na página. Eu usei essa API com o Google Maps.
jeff7091
3
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];foi um salva-vidas para mim várias vezes agora. Parece retornar do documento o máximo possível.
Ennalax
2
@ Hanuman Isso pode ajudá-lo: NSString * head = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.head.innerHTML"]; NSString * body = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.body.innerHTML"]; NSString * totalPage = anexa as duas strings.
Deepukjayan
91

se você deseja extrair o conteúdo de um UIWebView já carregado, -stringByEvaluatingJavaScriptFromString. Por exemplo:

NSString  *html = [webView stringByEvaluatingJavaScriptFromString: @"document.body.innerHTML"];
Ben Gottlieb
fonte
10
Porra, isso é inteligente!
precisa saber é o seguinte
2
A pergunta que tenho é o que acontece se o conteúdo for uma sequência JSON ou mesmo uma sequência bruta sem uma etiqueta corporal.
stephenmuss
Esta não é uma solução saudável! Todas as informações do código javascript e do cabeçalho são perdidas dessa maneira.
Radu Simionescu
43

Para obter todos os dados brutos em HTML (com <head>e <body>):

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

Observe que a stringStringWithContentsOfURL do NSString relatará uma string de agente do usuário totalmente diferente da UIWebView que faz a mesma solicitação. Portanto, se seu servidor estiver ciente do agente do usuário e enviando de volta um html diferente, dependendo de quem está solicitando, talvez você não obtenha resultados corretos dessa maneira.

Observe também que o @"document.body.innerHTML"mencionado acima exibirá apenas o que está na etiqueta do corpo. Se você usar, @"document.all[0].innerHTML"terá cabeça e corpo. Ainda não é o conteúdo completo do UIWebView, pois não receberá as tags! Doctype ou html, mas está muito mais próximo.

Pmatt
fonte
Teoricamente, você pode obter o doctype solicitando-o ao servidor. É provável que o doctype não seja alterado com base no useragent.
Moshe
20

Ler:-

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

Para modificar:-

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

No Swift v3:

let doc = webView.stringByEvaluatingJavaScript(from: "document.documentElement.outerHTML")
Mc.Lover
fonte
1

Eu uso uma extensão rápida como esta:

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

}
Nathan
fonte
1

você deve tentar o seguinte:

document.documentElement.outerHTML
schumyxp
fonte
1

UIWebView

obter HTML do UIWebView`

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

definir HTML em 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
}

[obter / definir HTML do WKWebView]

yoAlex5
fonte