การอ่านเนื้อหา HTML จาก UIWebView


132

เป็นไปได้ไหมที่จะอ่านเนื้อหา HTML ดิบของหน้าเว็บที่โหลดลงใน a UIWebView?

หากไม่เป็นเช่นนั้นมีวิธีอื่นในการดึงเนื้อหา HTML ดิบจากหน้าเว็บใน iPhone SDK (เช่นไฟล์. 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];

แก้ไข:ทั้งสองวิธีนี้ได้รับผลกระทบด้านประสิทธิภาพเนื่องจากพวกเขาทำคำขอสองครั้ง คุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยการดึงเนื้อหาจาก UIWebView ที่โหลดในปัจจุบันโดยใช้stringByEvaluatingJavascriptFromString:วิธีการดังต่อไปนี้:

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

สิ่งนี้จะดึงเนื้อหา HTML ปัจจุบันของมุมมองโดยใช้ Document Object Model แยกวิเคราะห์ JavaScript จากนั้นให้เป็น NSString * ของ HTML

อีกวิธีหนึ่งคือทำตามคำขอของคุณโดยใช้โปรแกรมก่อนจากนั้นโหลด UIWebView จากสิ่งที่คุณร้องขอ สมมติว่าคุณใช้ตัวอย่างที่สองดังกล่าวข้างต้นที่คุณจะต้องเป็นผลมาจากการเรียกร้องให้มีNSString *page stringWithContentsOfURL:encoding:error:จากนั้นคุณสามารถพุชสตริงนั้นในมุมมองเว็บโดยใช้loadHTMLString:baseURL:สมมติว่าคุณอยู่ใน NSURL ที่คุณร้องขอ:

[yourWebView loadHTMLString:page baseURL:requestURL];

อย่างไรก็ตามฉันไม่แน่ใจว่าจะเรียกใช้ JavaScript ที่พบในหน้าที่คุณโหลดได้หรือไม่ (ชื่อวิธีการloadHTMLStringค่อนข้างคลุมเครือและเอกสารไม่ได้พูดถึงมันมากนัก)

สำหรับข้อมูลเพิ่มเติม:

  • การอ้างอิงคลาสUIWebView
  • การอ้างอิงคลาสNSString
  • การอ้างอิงคลาสNSURL

1
สุดยอด! ขอบคุณสำหรับคำตอบที่ดี ฉันคิดว่าทั้งสองวิธีส่งผลให้เพจถูกโหลดสองครั้งซึ่งอาจมีผลกระทบต่อประสิทธิภาพ มีวิธีหลีกเลี่ยงหรือไม่?
Fuzzy Purple Monkey

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 stringByEvaliftingJavaScriptFromString: @ "document.head.innerHTML"]; NSString * body = [yourWebView stringByEvaliftingJavaScriptFromString: @ "document.body.innerHTML"]; NSString * totalPage = ผนวกทั้งสองสตริง
Deepukjayan

91

หากคุณต้องการแยกเนื้อหาของ UIWebView ที่โหลดไว้แล้ว -stringByEvaliftingJavaScriptFromString ตัวอย่างเช่น:

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

10
ไอ้ที่ฉลาด!
jemmons

2
คำถามที่ฉันมีคือจะเกิดอะไรขึ้นถ้าเนื้อหาเป็นสตริง JSON หรือแม้แต่สตริงดิบที่ไม่มีแท็กเนื้อหา
stephenmuss

นี่ไม่ใช่ทางออกที่ดีต่อสุขภาพ! รหัสจาวาสคริปต์และข้อมูลส่วนหัวทั้งหมดจะหายไปด้วยวิธีนี้
Radu Simionescu

43

ในการรับข้อมูลดิบ HTML ทั้งหมด (พร้อม<head>และ<body>):

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

29

โปรดทราบว่า NSString stringWithContentsOfURL จะรายงานสตริง User-agent ที่แตกต่างจาก UIWebView ที่สร้างคำขอเดียวกัน ดังนั้นหากเซิร์ฟเวอร์ของคุณรับรู้ User-agent และส่งกลับ html ที่แตกต่างกันขึ้นอยู่กับว่าใครเป็นผู้ร้องขอคุณอาจไม่ได้รับผลลัพธ์ที่ถูกต้องด้วยวิธีนี้

โปรดทราบว่าสิ่งที่@"document.body.innerHTML"กล่าวถึงข้างต้นจะแสดงเฉพาะสิ่งที่อยู่ในแท็กเนื้อหา หากคุณใช้@"document.all[0].innerHTML"คุณจะได้รับทั้งศีรษะและลำตัว ซึ่งยังไม่ใช่เนื้อหาที่สมบูรณ์ของ UIWebView เนื่องจากจะไม่ได้รับแท็ก! Doctype หรือ html กลับคืนมา แต่มันใกล้กว่ามาก


ในทางทฤษฎีคุณสามารถรับประเภทหลักได้โดยการขอจากเซิร์ฟเวอร์ มีแนวโน้มว่าประเภทหลักจะไม่เปลี่ยนแปลงตาม useragent
Moshe

20

อ่าน:-

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

ในการปรับเปลี่ยน:-

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



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]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.