Читання HTML-вмісту з UIWebView


132

Чи можна прочитати сирий HTML-вміст веб-сторінки, завантаженої у UIWebView?

Якщо ні, чи є інший спосіб витягнути сирий HTML-вміст із веб-сторінки в SDK для iPhone (наприклад, еквівалент .NET WebClient::openRead)?

Відповіді:


216

На друге питання насправді простіше відповісти. Подивіться на stringWithContentsOfURL:encoding:error:метод NSString - він дозволяє переходити за 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) трохи складніше, але в основному той самий поняття. Вам потрібно буде витягнути запит із подання, а потім зробити це, як раніше:

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 , є дещо неоднозначним, і документи не говорять про це багато).

Для отримання додаткової інформації:


1
Дивовижно! Дякую за чудову відповідь. Я припускаю, що обидва способи призводять до завантаження сторінки двічі, що може мати вплив на ефективність. Чи є спосіб уникнути цього?
Fuzzy Purple Monkey

2
Власне, є :) Відредагована відповідь.
Тім

1
Так, [yourWebView loadHTMLString: сторінка baseURL: requestURL]; запустить Javascript на сторінці. Я використовував цю програму з картами Google.
jeff7091

3
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];був рятівним рятувальником для мене вже кілька разів. Здається, повертається з документа якнайбільше.
енналакс

2
@Hanuman Це може допомогти вам: NSString * head = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.head.innerHTML"]; NSString * body = [yourWebView stringByEvaluatingJavaScriptFromString: @ "document.body.innerHTML"]; NSString * totalPage = додати обидва рядки.
Deepukjayan

91

якщо ви хочете витягти вміст уже завантаженого UIWebView, -stringByEvaluatingJavaScriptFromString. Наприклад:

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

10
Чорт, це розумно!
Джеммони

2
У мене виникає запитання: що відбувається, якщо вміст є рядком JSON або навіть необробленим рядком без тега body?
stephenmuss

Це не здорове рішення! Вся інформація про код JavaScript та заголовки втрачається таким чином.
Раду Сіміонеску

43

Щоб отримати цілі вихідні дані HTML (з <head>та <body>):

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

29

Зауважте, що рядок NSStringWithContentsOfURL повідомить про зовсім інший рядок агента користувача, ніж UIWebView, що робить той самий запит. Отже, якщо ваш сервер обізнаний з користувачем-агентом, і надсилаючи назад різні HTML-файли, залежно від того, хто просить, ви, таким чином, не зможете отримати правильних результатів.

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


Теоретично ви можете отримати вчення, подавши запит на сервер. Цілком імовірно, що вчення не зміниться на основі useragent.
Моше

20

Читати:-

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

Для зміни: -

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

2

У Swift v3:

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


1

Я використовую таке швидке розширення:

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

}


1

UIWebView

отримати HTML від UIWebView`

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

встановити HTML в 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 від WKWebView]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.