Đọc nội dung HTML từ UIWebView


132

Có thể đọc nội dung HTML thô của một trang web đã được tải vào UIWebViewkhông?

Nếu không, có cách nào khác để lấy nội dung HTML thô từ một trang web trong SDK iPhone (chẳng hạn như tương đương với .NET WebClient::openRead) không?

Câu trả lời:


216

Câu hỏi thứ hai thực sự dễ trả lời hơn. Hãy xem stringWithContentsOfURL:encoding:error:phương pháp của NSString - nó cho phép bạn chuyển một URL dưới dạng một thể hiện của NSURL (có thể dễ dàng được tạo ngay từ NSString) và trả về một chuỗi có nội dung đầy đủ của trang tại URL đó. Ví dụ:

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

Sau khi chạy mã này, googlePagesẽ chứa HTML cho www.google.com và errorsẽ chứa bất kỳ lỗi nào gặp phải trong quá trình tìm nạp. (Bạn nên kiểm tra nội dung errorsau khi tìm nạp.)

Đi theo một cách khác (từ UIWebView) phức tạp hơn một chút, nhưng về cơ bản là cùng một khái niệm. Bạn sẽ phải lấy yêu cầu từ chế độ xem, sau đó thực hiện tìm nạp như trước:

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

EDIT: Tuy nhiên, cả hai phương pháp này đều đạt hiệu quả cao, vì chúng thực hiện yêu cầu hai lần. Bạn có thể khắc phục điều này bằng cách lấy nội dung từ UIWebView hiện đang được tải bằng stringByEvaluatingJavascriptFromString:phương thức của nó , như sau:

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

Điều này sẽ lấy nội dung HTML hiện tại của chế độ xem bằng Mô hình Đối tượng Tài liệu, phân tích cú pháp JavaScript, sau đó cung cấp cho bạn dưới dạng NSString * của HTML.

Một cách khác là thực hiện yêu cầu của bạn theo chương trình trước, sau đó tải UIWebView từ những gì bạn yêu cầu. Giả sử bạn lấy ví dụ thứ hai ở trên, nơi bạn có NSString *pagekết quả của một cuộc gọi đến stringWithContentsOfURL:encoding:error:. Sau đó, bạn có thể đẩy chuỗi đó vào chế độ xem web bằng cách sử dụng loadHTMLString:baseURL:, giả sử bạn cũng đã giữ NSURL mà bạn yêu cầu:

[yourWebView loadHTMLString:page baseURL:requestURL];

Tuy nhiên, tôi không chắc chắn nếu điều này sẽ chạy JavaScript được tìm thấy trong trang bạn tải (tên phương thức loadHTMLString, hơi mơ hồ và các tài liệu không nói nhiều về nó).

Để biết thêm thông tin:


1
Tuyệt vời! Cảm ơn câu trả lời tuyệt vời. Tôi cho rằng cả hai phương pháp đều dẫn đến việc trang được tải hai lần, điều này có thể có tác động đến hiệu suất. Có cách nào để tránh điều đó?
Khỉ tím mờ

2
Như một vấn đề của thực tế, có :) Câu trả lời được chỉnh sửa.
Tim

1
Có, [yourWebView loadHTMLString: page baseURL: requestURL]; sẽ chạy Javascript trong trang. Tôi đã sử dụng api này với bản đồ Google.
jeff7091

3
NSString *html = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML"];đã là cứu cánh cho tôi nhiều lần Nó dường như trở về từ tài liệu càng nhiều càng tốt.
ennalax

2
@Hanuman Điều này có thể giúp bạn: NSString * head = [yourWebView chuỗiByEvaluatingJavaScriptFromString: @ "document.head.innerHTML"]; NSString * body = [yourWebView chuỗiByEvaluatingJavaScriptFromString: @ "document.body.innerHTML"]; NSString * totPage = nối cả hai chuỗi.
Deepukjaya

91

nếu bạn muốn trích xuất nội dung của UIWebView đã được tải,-chuỗiByEvaluatingJavaScriptFromString. Ví dụ:

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

10
Chết tiệt, thật thông minh!
jemmons

2
Câu hỏi tôi có là điều gì xảy ra nếu nội dung xảy ra là một chuỗi JSON hoặc thậm chí là một chuỗi thô không có thẻ body?
stephenmuss

Đây không phải là một giải pháp lành mạnh! Tất cả các mã javascript và thông tin tiêu đề bị mất theo cách này.
Radu Simionescu

43

Để lấy toàn bộ dữ liệu thô HTML (có <head><body>):

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

29

Lưu ý rằng chuỗi NSStringWithContentsOfURL sẽ báo cáo một chuỗi tác nhân người dùng hoàn toàn khác so với UIWebView thực hiện cùng một yêu cầu. Vì vậy, nếu máy chủ của bạn nhận biết tác nhân người dùng và gửi lại html khác nhau tùy thuộc vào người đang yêu cầu, bạn có thể không nhận được kết quả chính xác theo cách này.

Cũng lưu ý rằng những điều @"document.body.innerHTML"được đề cập ở trên sẽ chỉ hiển thị những gì có trong thẻ body. Nếu bạn sử dụng, @"document.all[0].innerHTML"bạn sẽ nhận được cả đầu và cơ thể. Đây vẫn chưa phải là nội dung đầy đủ của UIWebView, vì nó sẽ không lấy lại các thẻ! Doctype hoặc html, nhưng nó gần hơn rất nhiều.


Về mặt lý thuyết, bạn có thể lấy tài liệu bằng cách yêu cầu nó từ máy chủ. Có khả năng là loại tài liệu sẽ không thay đổi dựa trên người dùng.
Moshe

20

Đọc:-

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

Để sửa đổi:-

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

2

Trong Swift v3:

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


1

Tôi sử dụng một phần mở rộng nhanh như thế này:

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

}

1

bạn nên thử điều này:

document.documentElement.outerHTML

1

Giao diện người dùng

lấy HTML từ UIWebView`

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

đặt HTML vào 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
}

[nhận / đặt HTML từ WKWebView]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.