1. ข้อกำหนด
เมื่อเร็ว ๆ นี้ฉันได้ปรับเปลี่ยนแอพข่าวของฉันเองตามการออกแบบวัสดุและแหล่งที่มาของข้อมูลเป็นปัญหา
บรรพบุรุษได้วิเคราะห์ APIs เช่น Zhihu Daily และ Phoenix News และสามารถรับข้อมูลข่าว JSON ตาม URL ที่เกี่ยวข้อง เพื่อใช้ทักษะการเขียนรหัสผู้เขียนวางแผนที่จะรวบรวมข้อมูลหน้าข่าวและรับข้อมูลด้วยตัวเองเพื่อสร้าง API
2. ภาพเอฟเฟกต์
ภาพด้านล่างคือหน้าของเว็บไซต์ต้นฉบับ
ตัวรวบรวมข้อมูลได้รับข้อมูลและแสดงไปยังเทอร์มินัลมือถือของแอพ
3. ไอเดียการรวบรวมข้อมูล
สำหรับกระบวนการใช้งานแอพคุณสามารถอ้างถึงบทความเหล่านี้ บทความนี้ส่วนใหญ่จะอธิบายถึงวิธีการรวบรวมข้อมูล
กระบวนการทั้งหมดของการบันทึกการดำเนินการแอพบน Android เพื่อสร้าง GIF Dynamic Pictures: //www.vevb.com/article/78236.htm
เรียนรู้การออกแบบวัสดุ Android (Recyclerview แทน listView): //www.vevb.com/article/78232.htm
Android Project การเลียนแบบหน้าข่าว NetEase (Recyclerview): //www.vevb.com/article/78230.htm
รู้เบื้องต้นเกี่ยวกับ JSoup
JSOUP เป็นตัวแยกวิเคราะห์ HTML โอเพ่นซอร์สสำหรับ Java ซึ่งสามารถแยกวิเคราะห์ที่อยู่ URL และเนื้อหาข้อความ HTML ได้โดยตรง
JSOUP ส่วนใหญ่มีฟังก์ชั่นต่อไปนี้:
4. กระบวนการคลาน
รับคำขอเพื่อรับหน้าเว็บ html
ต้นไม้ DOM ของหน้าเว็บข่าว HTML มีดังนี้:
รหัสต่อไปนี้ใช้รหัสเพื่อรับซอร์สโค้ด HTML ที่ส่งคืนโดยคำขอ GET ตาม URL ที่ระบุ
สตริงคงที่สาธารณะ DOGET (String urlstr) พ่น commonexception {url url; สตริง html = ""; ลอง {url = url ใหม่ (urlstr); การเชื่อมต่อ httpurlConnection = (httpurlConnection) url.openconnection (); Connection.setRequestMethod ("รับ"); Connection.setConnectTimeOut (5000); Connection.setDoInput (จริง); Connection.setDooutput (จริง); if (connection.getResponsecode () == 200) {inputStream ใน = connection.getInputStream (); html = streamtool.intostringbybyte (in); } else {โยน commonexception ใหม่ ("ค่าส่งคืนเซิร์ฟเวอร์ข่าวไม่ใช่ 200"); }} catch (exception e) {e.printstacktrace (); โยน commonexception ใหม่ ("รับคำขอล้มเหลว"); } ส่งคืน html;}inputStream ใน = connection.getInputStream (); การแปลงกระแสอินพุตที่ได้เป็นสตริงเป็นข้อกำหนดทั่วไป เราสรุปมันออกมาและเขียนวิธีการเครื่องมือ
StreamTool ระดับสาธารณะ {สตริงคงที่สาธารณะ IntoStringByByte (inputStream) โยนข้อยกเว้น {ByTeArrayOutputStream Outstr = new ByteArrayOutputStream (); ไบต์ [] บัฟเฟอร์ = ไบต์ใหม่ [1024]; int len = 0; StringBuilder Content = new StringBuilder (); ในขณะที่ ((len = in.read (บัฟเฟอร์))! = -1) {content.append (สตริงใหม่ (บัฟเฟอร์, 0, len, "utf -8")); } outstr.close (); คืนเนื้อหา. tostring (); -5. การแยกวิเคราะห์ HTML เพื่อรับชื่อ
ใช้องค์ประกอบการเซ็นเซอร์ของ Google เบราว์เซอร์เพื่อค้นหารหัส HTML สำหรับชื่อข่าว:
<div id = "article_title"> <h1> <a href = "http://see.xidian.edu.cn/html/news/7428.html"> แจ้งให้ทราบล่วงหน้าเกี่ยวกับการบรรยายเรื่อง "การชื่นชมดนตรีคลาสสิก
เราจำเป็นต้องค้นหาส่วนหนึ่งของ id = "article_title" จาก HTML ด้านบนและใช้วิธี GetElementById (String ID)
String htmlstr = httptool.doget (urlstr); // แปลงรหัสแหล่งที่มา HTML ที่ได้รับของเว็บเพจเป็นเอกสาร Document doc = jsoup.parse (htmlstr); องค์ประกอบ stricanele = doc.getElementId ("บทความ"); //6. รับวันที่วางจำหน่ายและแหล่งข้อมูล
หารหัส HTML สำหรับ
<html> <head> </head> <body> <div id = "article_detail"> <span> 2015-05-28 </span> <span> แหล่งที่มา: </span> <pan> จำนวนการดู: <script language = "JavaScript" src = "http://see.xidian.edu.cnindex.cnind 477 </span> </div> </body> </html>
ความคิดนั้นคล้ายกับข้างต้น ใช้วิธี GetElementById (String ID) เพื่อค้นหาว่า id = "article_detail" เป็นองค์ประกอบจากนั้นใช้ getElementsByTag เพื่อรับส่วนขยาย เนื่องจากมี 3 <span> ... </span> โดยรวมองค์ประกอบจะถูกส่งคืนแทนองค์ประกอบ
// article_detail รวมถึง 2016-01-15 ที่มา: มุมมอง: 177Element Detailele = articleele.getElementById ("article_detail"); องค์ประกอบรายละเอียด = detailele.getElementsByTag ("span");7. จำนวนครั้งของการวิเคราะห์
หากคุณพิมพ์รายละเอียดด้านบน (2) .Text () คุณจะได้รับเฉพาะ
จำนวนมุมมอง:
ไม่มีมุมมอง? ทำไม
เนื่องจากจำนวนมุมมองที่แสดงโดย JavaScript JSOUP Crawler อาจแยกเนื้อหา HTML เท่านั้นและไม่สามารถรับข้อมูลที่แสดงผลแบบไดนามิกได้
มีสองวิธีแก้ปัญหา
หากคุณเยี่ยมชม urlhttp ข้างต้น: //see.xidian.edu.cn/index.php/news/click/id/7428 คุณจะได้รับผลลัพธ์ต่อไปนี้
document.write (478)
478 นี้คือจำนวนมุมมองที่เราต้องการ เราทำการร้องขอ GET สำหรับ URL ข้างต้นรับสตริงที่ส่งคืนและใช้ปกติเพื่อค้นหาหมายเลขในนั้น
// เมื่อเยี่ยมชมหน้าข่าวนี้จำนวนการดูจะเป็น +1 และจำนวนครั้งคือสตริงที่แสดงโดย js jsstr = httptool.doget (count_base_url + currentPage); int readtimes = integer.parseint (jsstr.replaceall ("// d+", "")); // หรือใช้วิธีปกติต่อไปนี้ // สตริง readtimesstr = jsstr.replaceall ("[^0-9]", "");8. วิเคราะห์เนื้อหาข่าว
เดิมทีมันเป็นรูปแบบของการได้รับเนื้อหาข่าวในข้อความธรรมดา แต่ต่อมาก็พบว่าด้าน Android สามารถแสดงรูปแบบ CSS ได้ดังนั้นเนื้อหาจะถูกเก็บไว้ในรูปแบบ HTML ในภายหลัง
Element ContentEle = articleele.getElementById ("article_content"); // นิวส์เนื้อหาเนื้อหาสตริงเนื้อหา String string = contentele.toString (); // ถ้าใช้ข้อความ () วิธีการใช้แท็ก html ของเนื้อหาร่างกายข่าวจะหายไป //9. วิเคราะห์ URL รูปภาพ
โปรดทราบว่ามีรูปภาพขนาดใหญ่และขนาดเล็กจำนวนมากบนหน้าเว็บ เพื่อที่จะได้รับเนื้อหาในข้อความข่าวเท่านั้นจึงเป็นการดีที่สุดที่จะค้นหาองค์ประกอบของเนื้อหาข่าวก่อนแล้วใช้ GetElementsByTag ("IMG") เพื่อกรองรูปภาพ
Element contentele = articleele.getElementById ("article_content"); // ข่าวเนื้อหาเนื้อหาเนื้อหาสตริง contentstr = contentele.toString (); // ถ้าใช้ข้อความ () วิธีการใช้วิธี html แท็กของเนื้อหาร่างกายจะหายไป contentele.getElementsByTag ("img"); string [] imageUrls = สตริงใหม่ [images.size ()]; สำหรับ (int i = 0; i <imageUrls.length; i ++) {imageUrls [i] = images.get (i)10. นิวส์นิติบุคคล Javabean
ข้างต้นคือการได้รับชื่อวันที่วางจำหน่ายจำนวนการอ่านเนื้อหาข่าว ฯลฯ ของข่าว เราจำเป็นต้องสร้าง javabean และห่อหุ้มเนื้อหาที่ได้รับลงในคลาสเอนทิตี
Public Class PraticleItem {ดัชนี INT ส่วนตัว; สตริงส่วนตัว [] ImageUrls; ชื่อสตริงส่วนตัว; Private String PublishDate; แหล่งสตริงส่วนตัว INT readtimes ส่วนตัว; ตัวสตริงส่วนตัว; Public AttricateItem (INT ดัชนี, String [] ImageUrls, ชื่อสตริง, สตริง publishDate, แหล่งที่มาของสตริง, int readtimes, สตริงตัว) {this.index = index; this.imageUrls = imageUrls; this.title = title; this.publishDate = PublishDate; this.source = แหล่งที่มา; this.readTimes = readTimes; this.body = body; } @Override สตริงสาธารณะ toString () {return "articleItem [index =" + index + ",/n imageUrls =" + array.toString (ImageUrls) + ",/n,/n publishDate =" + publishDate + ",/n แหล่งที่มา =" + แหล่งที่มา + " -ทดสอบ
Public Static PraticleItem GetNewsItem (int currentPage) พ่น commonexception {// ตามหมายเลขคำต่อท้าย, splice url url สตริงข่าว urlstr = article_base_url + currentPage + ".html"; สตริง htmlstr = httptool.doget (urlstr); เอกสารเอกสาร = jsoup.parse (htmlstr); องค์ประกอบบทความ = doc.getElementById ("บทความ"); // ชื่อองค์ประกอบ titleele = articleele.getElementById ("article_title"); สตริง titLestr = titleele.text (); // article_detail รวมถึง 2016-01-15 ที่มา: มุมมอง: 177 Element Detailele = articleele.getElementById ("article_detail"); รายละเอียดองค์ประกอบ = detailele.getElementsByTag ("span"); // สตริงเวลาที่วางจำหน่าย datestr = details.get (0) .text (); // สตริงต้นฉบับข่าว sourcestr = details.get (1) .Text (); // เยี่ยมชมหน้าข่าวนี้และจำนวนการดูจะเป็น +1 ซึ่งเป็นจำนวนครั้งที่ JS แสดงผล jsstr = httptool.doget (count_base_url + currentPage); int readtimes = integer.parseint (jsstr.replaceall ("// d+", "")); // หรือใช้วิธีปกติต่อไปนี้ // สตริง readTimessTr = jsstr.replaceall ("[^0-9]", ""); Element ContentEle = articleele.getElementById ("article_content"); // นิวส์เนื้อหาเนื้อหาสตริง contentstr = contentele.toString (); // ถ้าใช้วิธี text () แท็ก HTML ของเนื้อหาเนื้อหาข่าวจะหายไป // เพื่อแสดง HTML ด้วย WebView บน Android ให้ใช้ toString () // String contentstr = contentele.Text (); Elements images = contentele.getElementsByTag ("IMG"); สตริง [] imageUrls = สตริงใหม่ [images.size ()]; สำหรับ (int i = 0; i <imageUrls.length; i ++) {imageUrls [i] = images.get (i) .attr ("src"); } ส่งคืนบทความใหม่ (CurrentPage, ImageUrls, titlestr, datestr, sourcestr, readtimes, contentSTR);} โมฆะคงที่สาธารณะหลัก (สตริง [] args) พ่น commonexception {system.out.println (getNewsItem (7928));ข้อมูลผลลัพธ์
บทความ [ดัชนี = 7928, ImageUrls = [/uploads/image/20160114/20160114225911_34428.png] ชื่อ = โรงเรียนวิศวกรรมไฟฟ้าเปิดตัว id = "article_content"> <p style = "Indentent: 2EM;" Align = "Justify"> <strong> <span style = "font-size: 16px; line-height: 1.5;"> Xidian News Network </span> </strong> <span style = "Font-Size: 16px; Line-Height: 1.5;"> Dan </span> </strong> <span style = "Font-Size: 16px; Line-Height: 1.5;"> ... )
บทความนี้อธิบายวิธีการใช้งาน JSOUP Web Crawler หากบทความมีประโยชน์สำหรับคุณให้ยกนิ้วให้ฉัน