从UIWebView读取HTML内容


132

是否可以读取已加载到中的网页的原始HTML内容UIWebView

如果不是,是否还有另一种方法可以从iPhone SDK中的网页中提取原始HTML内容(如.NET的等价内容WebClient::openRead)?

Answers:


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将包含www.google.com的HTML,error并将包含提取中遇到的所有错误。(您应error在提取后检查的内容。)

换种方式(从UIWebView)比较麻烦,但是基本上是相同的概念。您必须从视图中拉出请求,然后像以前一样进行提取:

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

编辑:但是,这两种方法都会对性能造成影响,因为它们两次执行了请求。您可以通过使用其stringByEvaluatingJavascriptFromString:方法从当前加载的UIWebView中获取内容来解决此问题,如下所示:

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

这将使用文档对象模型获取视图的当前HTML内容,解析JavaScript,然后将其作为HTML的NSString *提供给您。

另一种方法是首先以编程方式执行您的请求,然后从您的请求中加载UIWebView。假设您举了上面的第二个示例,您在其中NSString *page调用了stringWithContentsOfURL:encoding:error:。然后,您可以使用将该字符串推送到Web视图中loadHTMLString:baseURL:,前提是您还保留了所请求的NSURL:

[yourWebView loadHTMLString:page baseURL:requestURL];

但是,我不确定这是否将运行您加载的页面中找到的JavaScript(方法名称loadHTMLString有点模棱两可,并且文档对此不多说)。

有关更多信息:


1
太棒了!感谢您的出色回答。我认为这两种方法都会导致页面被加载两次,这可能会对性能产生影响。有办法避免这种情况吗?
模糊的紫色猴子,

2
实际上,有:)编辑的答案。
蒂姆

1
是的,[yourWebView loadHTMLString:page baseURL:requestURL]; 将在页面中运行Javascript。我已经将此API与Google Maps结合使用了。
jeff7091

3
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];对我来说,已经好几次了。它似乎尽可能从文档中返回。
ennalax

2
@Hanuman这可能会帮助您:NSString * head = [yourWebView stringByEvaluatingJavaScriptFromString:@“ document.head.innerHTML”]; NSString * body = [yourWebView stringByEvaluatingJavaScriptFromString:@“ document.body.innerHTML”]; NSString * totalPage =追加两个字符串。
Deepukjayan 2012年

91

如果要提取已加载的UIWebView的内容,请使用-stringByEvaluatingJavaScriptFromString。例如:

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

10
该死的,那很聪明!
jemmons

2
我的问题是,如果内容恰好是JSON字符串甚至是没有body标签的原始字符串,会发生什么?
stephenmuss

这不是一个健康的解决方案!所有的JavaScript代码和标头信息都以这种方式丢失。
Radu Simionescu

43

要获取完整的HTML原始数据(使用<head><body>):

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

29

请注意,NSString stringWithContentsOfURL将报告与发出相同请求的UIWebView完全不同的用户代理字符串。因此,如果您的服务器支持用户代理,并且根据谁要求发送不同的html,您可能无法通过这种方式获得正确的结果。

另外请注意,@"document.body.innerHTML"上述内容只会显示body标签中的内容。如果您使用,@"document.all[0].innerHTML"您将得到头部和身体。这仍然不是UIWebView的完整内容,因为它不会取回!doctype或html标记,但是距离更近了。


从理论上讲,您可以通过从服务器请求文档类型获取它。doctype可能不会根据useragent更改。
Moshe

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

您应该尝试这样:

document.documentElement.outerHTML

1

UIWebView

从UIWebView获取HTML`

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
}

[从WKWebView获取/设置HTML]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.