2009-06-14 5 views
125

Возможно ли прочитать исходный HTML-контент веб-страницы, загруженной в UIWebView?Чтение содержимого HTML из UIWebView

Если нет, есть ли способ вытащить необработанный HTML-контент с веб-страницы в SDK iPhone (например, эквивалент .NET WebClient::openRead)?

ответ

207

Второй вопрос на самом деле проще ответить. Посмотрите на метод NSString stringWithContentsOfURL:encoding:error: - он позволяет передавать URL-адрес как экземпляр NSURL (который может быть легко создан из NSString) и возвращает строку с полным содержимым страницы по этому URL-адресу. Например:

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

После выполнения этого кода, googlePage будет содержать HTML для www.google.com и error будет содержать любые ошибки, возникающие в выборку. (Вы должны проверить содержимое error после извлечения.)

Идти другим путем (из UIWebView) немного сложнее, но в основном является той же концепцией. Вы должны будете тянуть request с точки зрения, то делать выборки, как и раньше:

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

EDIT: Оба эти метода принимают удар по производительности, однако, так как они делают запрос дважды. Вы можете обойти эту проблему путем захвата содержимого из текущей загруженной UIWebView, используя свой метод stringByEvaluatingJavascriptFromString:, как таковой:

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

Это будет захватывать текущее содержимое HTML из представления с помощью объектной модели документа, разобрать JavaScript, затем дайте его вам как NSString * HTML.

Другой способ - сделать ваш запрос программно сначала, а затем загрузить UIWebView из того, что вы запросили. Предположим, вы взяли второй пример выше, где у вас есть NSString *page в результате звонка на stringWithContentsOfURL:encoding:error:. После этого вы можете нажать эту строку в веб-просмотра с помощью loadHTMLString:baseURL:, если вы также состоялось в NSURL вы просили:

[yourWebView loadHTMLString:page baseURL:requestURL]; 

Я не уверен, однако, если это будет работать JavaScript найти на странице загружаемой (имя метода, loadHTMLString, несколько неоднозначно, и документы не говорят об этом много).

Для получения дополнительной информации:

  • UIWebView эталонного класса
  • NSString класса эталонного
  • NSURL класса эталонного
+1

Awesome! Спасибо за отличный ответ. Я предполагаю, что оба метода приводят к загрузке страницы дважды, что может повлиять на производительность. Есть ли способ избежать этого? –

+2

На самом деле есть :) Отредактированный ответ. – Tim

+1

Да, [yourWebView loadHTMLString: страница baseURL: requestURL]; запустит Javascript на странице. Я использовал этот api с картами Google. – jeff7091

88

, если вы хотите, чтобы извлечь содержимое уже загруженный UIWebView, - stringByEvaluatingJavaScriptFromString.Например:

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

Черт, это умно! – jemmons

+2

Вопрос, который у меня есть, заключается в том, что происходит, если контент является строкой JSON или даже необработанной строкой без тега body? – stephenmuss

+0

Это не здоровое решение! Весь код javascript и информация заголовка теряются таким образом. –

19

следующим образом: -

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

Для изменения: -

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

Обратите внимание, что NSString stringWithContentsOfURL сообщит совершенно другую строку агента пользователя, чем изготовление UIWebView тот же запрос. Поэтому, если ваш сервер является агентом-агентом и он отправляет обратно другой html в зависимости от того, кто его запрашивает, вы можете не получить правильные результаты таким образом.

Также обратите внимание, что упомянутый выше @"document.body.innerHTML" отобразит только те теги тела. Если вы используете @"document.all[0].innerHTML", вы получите как голову, так и тело. Это все еще не полное содержимое UIWebView, так как оно не вернет теги! Doctype или html, но это намного ближе.

+0

Теоретически вы * можете * получить doctype, запросив его с сервера. Вполне вероятно, что doctype не изменится на основе useragent. – Moshe

40

Чтобы получить весь HTML исходных данных (с <head> и <body>):

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

вы должны попробовать это:

document.documentElement.outerHTML

0

В SWIF т v3:

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

Я использую быстрое расширение, как это:

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

} 
Смежные вопросы