คำนำ: ก่อนที่จะเขียนบทความนี้ส่วนใหญ่ฉันอ่านรูปแบบการเขียนตัวรวบรวมข้อมูลที่คล้ายกันบางอย่าง บางคนใช้คิวในการเขียนซึ่งรู้สึกว่าไม่ง่ายนัก บางคนมีคำขอเพียงครั้งเดียวจากนั้นทำการวิเคราะห์หน้า พวกเขาจะไม่ตื่นโดยอัตโนมัติเลย นี่เรียกอีกอย่างว่า Crawler? ดังนั้นฉันจึงเขียนเกี่ยวกับการรวบรวมข้อมูลง่ายๆตามความคิดของฉันเอง
การแนะนำอัลกอริทึม
โปรแกรมใช้อัลกอริทึมที่กว้างก่อนในความคิดของมันผู้เริ่มต้นจะได้รับการร้องขอสำหรับลิงก์ที่ไม่ได้รับความสนใจหนึ่งหลังจากนั้นแยกวิเคราะห์หน้ากลับด้วยการแสดงออกปกตินำลิงก์ใหม่ที่ไม่ได้ค้นพบเพิ่มเข้าไปในคอลเลกชัน
การใช้งานที่เฉพาะเจาะจงใช้แผนที่ <สตริงบูลีน> และคู่คีย์-ค่าเป็นลิงค์และจะข้ามไปหรือไม่ มีการใช้คอลเล็กชันแผนที่สองรายการในโปรแกรมคือ: OldMap และ NewMap ลิงค์เริ่มต้นอยู่ใน OldMap จากนั้นคำขอจะถูกสร้างขึ้นสำหรับลิงค์ที่มีการตั้งค่าสถานะ FALSE ใน OLDMAP แยกวิเคราะห์หน้าและใช้ปกติเพื่อลบลิงก์ภายใต้แท็ก <a> หากลิงค์นี้ไม่ได้อยู่ใน OldMap และ NewMap หมายความว่านี่เป็นลิงค์ใหม่ ในเวลาเดียวกันหากลิงค์นี้เป็นลิงค์ของเว็บไซต์เป้าหมายที่เราต้องได้รับเราจะใส่ลิงค์นี้ลงใน NewMap และแยกวิเคราะห์ต่อไป เมื่อหน้าถูกแยกวิเคราะห์ค่าของลิงก์ในหน้าปัจจุบันใน OldMap ถูกตั้งค่าเป็น TRUE ซึ่งหมายความว่ามันถูกสำรวจ
ในที่สุดเมื่อลิงค์ทั้งหมดที่ไม่ได้ถูกสำรวจโดย OldMap ได้ถูกสำรวจหากคุณพบว่า NEWMAP ไม่ว่างเปล่าหมายความว่าลิงก์ใหม่ได้ถูกสร้างขึ้นในวงนี้ ดังนั้นลิงก์ใหม่เหล่านี้จะถูกเพิ่มเข้าไปใน OldMap และดำเนินการต่อเพื่อสำรวจซ้ำ มิฉะนั้นหมายความว่าไม่มีการสร้างลิงก์ใหม่ในลูปนี้ หากคุณยังคงวนเวียนอยู่ต่อไปคุณไม่สามารถสร้างลิงค์ใหม่ได้อีกต่อไป เนื่องจากงานจบลงแล้ว Link Collection OldMap จะถูกส่งกลับ
การใช้งานโปรแกรมสองรายการ
แนวคิดที่เกี่ยวข้องข้างต้นได้รับการอธิบายอย่างชัดเจนและมีความคิดเห็นในประเด็นสำคัญในรหัสดังนั้นฉันจะไม่พูดถึงที่นี่รหัสมีดังนี้:
การกระทำของแพ็คเกจ; นำเข้า java.io.bufferedreader; นำเข้า java.io.ioexception; นำเข้า java.io.inputstream; นำเข้า java.io.inputstreamreader; นำเข้า java.net.httpurlconnection; นำเข้า Java.net.malformedurlexception; java.util.map; นำเข้า java.util.regex.matcher; นำเข้า java.util.regex.pattern; ชั้นเรียนสาธารณะ webcrawlerdemo {โมฆะคงที่สาธารณะหลัก (สตริง [] args) webcrawlerdemo.myprint ("http://www.zifangsky.cn"); } โมฆะสาธารณะ myPrint (String baseUrl) {แผนที่ <สตริง, บูลีน> oldMap = ใหม่ linkedHashMap <สตริง, บูลีน> (); // storage link- ไม่ว่าจะเป็น traversed // คีย์ค่าคู่สตริง oldlinkhost = ""; // รูปแบบโฮสต์ p = pattern.compile ("(https?: //)? [^/// s]*"); // ตัวอย่างเช่น: http://www.zifangsky.cn matcher m = p.matcher (baseUrl); if (m.find ()) {oldLinkHost = m.group (); } oldMap.put (baseUrl, false); oldMap = Crawllinks (OldLinkHost, OldMap); สำหรับ (map.entry <string, boolean> การแมป: oldMap.entrySet ()) {system.out.println ("ลิงก์:" + maping.getKey ()); }} /*** คลานลิงก์เว็บเพจทั้งหมดที่สามารถรวบรวมข้อมูลบนเว็บไซต์และใช้อัลกอริทึมลำดับความสำคัญที่กว้างในแนวคิด รับคำขอจะเริ่มต้นอย่างต่อเนื่องสำหรับลิงก์ใหม่ที่ไม่ได้ถูกสำรวจจนกว่าชุดทั้งหมดจะถูกสำรวจ ซึ่งหมายความว่าไม่สามารถพบลิงก์ใหม่ได้และงานจะสิ้นสุดลง * * @param oldlinkhost ชื่อโดเมนเช่น: http://www.zifangsky.cn * @param คอลเลกชัน OldMap ของลิงก์ที่จะสำรวจ * * @return {แผนที่ <สตริงบูลีน> newMap = ใหม่ linkedHashMap <สตริงบูลีน> (); สตริง oldLink = ""; สำหรับ (map.entry <string, boolean> การแมป: oldMap.entrySet ()) {system.out.println ("ลิงก์:" + maping.getKey () + "--------- ตรวจสอบ:" + maping.getValue ()); // ถ้ามันไม่ได้ถูกสำรวจโดย (! mapping.getValue ()) {oldLink = mapping.getKey (); // เริ่มคำขอรับ {url url = url ใหม่ (oldLink); การเชื่อมต่อ httpurlConnection = (httpurlConnection) url .openconnection (); Connection.setRequestMethod ("รับ"); Connection.setConnectTimeOut (2000); Connection.setReadtimeout (2000); if (connection.getResponsecode () == 200) {inputStream inputStream = connection.getInputStream (); bufferedReader reader = new BufferedReader (ใหม่ inputStreamReader (inputStream, "UTF-8")); สตริงบรรทัด = ""; รูปแบบรูปแบบ = รูปแบบ. compile ("<a.*? href = [/" ']? ((https?: //)?/? [^/"']+) [/" ']?.*?> (.+) </a> ") จับคู่ = null; {สตริง newLink = matcher.group (1) .trim (); OldLinkHost + "/" + newLink;} // ลบ/ที่ส่วนท้ายของลิงก์ถ้า (newLink.endswith ("/")) newLink = newLink.substring (0, newLink.length () newLink.startswith (oldlinkhost)) {// system.out.println ("temp2:" + newlink); Thread.sleep (1,000); } catch (interruptedException e) {e.printStackTrace (); } oldMap.replace (oldLink, false, true); }} // มีลิงก์ใหม่ดำเนินการต่อเพื่อสำรวจถ้า (! newMap.isEmpty ()) {oldMap.putAll (newMap); oldMap.putall (Crawllinks (OldLinkHost, OldMap)); // เนื่องจากลักษณะของแผนที่จะไม่มีคู่คีย์-ค่าซ้ำ} return oldMap; -ผลการทดสอบขั้นสุดท้ายสามผล
PS: ในความเป็นจริงการใช้การเรียกซ้ำนั้นไม่ค่อยดีนักเพราะหากเว็บไซต์มีหน้ามากขึ้นการใช้หน่วยความจำจะมีขนาดใหญ่มากหากโปรแกรมทำงานเป็นเวลานาน
ขอบคุณสำหรับการอ่านฉันหวังว่ามันจะช่วยคุณได้ ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!