مقدمة: قبل كتابة هذا المقال ، قرأت بشكل أساسي بعض أساليب كتابة الزاحف المماثلة. يستخدم بعضهم قوائم الانتظار لكتابتها ، والتي لا تبدو بديهية للغاية. لدى البعض طلب واحد فقط ثم إجراء تحليل الصفحة. إنهم لا ينهضون تلقائيًا على الإطلاق. وهذا ما يسمى أيضا الزاحف؟ لذلك ، كتبت عن زاحف بسيط بناءً على أفكاري الخاصة.
مقدمة خوارزمية
يستخدم البرنامج خوارزمية العرض الأول في فكرته ، وبدء الحصول على طلبات للحصول على روابط غير متوفرة واحدة تلو الأخرى ، ثم تخلق الصفحة التي تم إرجاعها مع تعبيرات منتظمة ، وتخرج الرابط الجديد الذي لم يتم اكتشافه ، ويضيفه إلى المجموعة ، ويجبرها في الحلقة التالية.
يستخدم التنفيذ المحدد MAP <String و Boolean> ، وأزواج القيمة الرئيسية هي الرابط وما إذا كان يجب اجتيازه. يتم استخدام مجموعتين من MAP في البرنامج ، وهما: 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.inputstreamread ؛ import java.net.httpurlconnection ؛ import java.net.malformedurlexception ؛ java.util.map ؛ import java.util.regex.matcher ؛ import java.util.regex.pattern ؛ public class webcrawlerdemo {public static void main (string [] args) {webCrawlerDemo webCrawlerDemo = New WebCrawlerDemo () ؛ WebCrawlerDemo.myprint ("http://www.zifangsky.cn") ؛ } public void myPrint (String baseurl) {map <string ، boolean> oldmap = new LinkedHashMap <string ، boolean> () ؛ // رابط التخزين-سواء تم اجتيازه // مفتاح القيمة زوج string OldLinkHost = "" ؛ // host pattern 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> mapping: oldmap.entryset ()) {system.out.println ("link:" + mapping.getKey ()) ؛ }} /*** قم بالزحف إلى جميع روابط صفحة الويب التي يمكن الزحف على موقع ويب ، واستخدم خوارزمية أولوية العرض في الفكرة. يتم بدء تشغيل الطلبات باستمرار للحصول على روابط جديدة لم يتم اجتيازها حتى يتم اجتياز المجموعة الكاملة. هذا يعني أنه لا يمكن العثور على روابط جديدة ، وتنتهي المهمة * * param oldlinkhost اسم المجال ، مثل: http://www.zifangsky.cn * @param oldmap collection of links to to transed * * return return all clawled link collections */private map <string ، boolean> crawllinks (string orting ، map < الخريطة <string ، boolean> newmap = new LinkedHashMap <string ، boolean> () ؛ String OldLink = "" ؛ لـ (map.entry <string ، boolean> mapping: oldmap.entryset ()) {system.out.println ("link:" + mapping.getKey () + "--------- check:" + mapping.getValue ()) ؛ // إذا لم يتم اجتيازه بواسطة (! mapping.getValue ()) {OldLink = mapping.getKey () ؛ // بدء طلب الحصول على جرب {url url = url new url (OldLink) ؛ HttpurlConnection Connection = (httpurlConnection) url .OpenConnection () ؛ connection.setRequestMethod ("get") ؛ connection.setConnectTimeout (2000) ؛ connection.setReadTimeout (2000) ؛ if (connection.getResPonsecode () == 200) {inputStream inputStream = connection.getInputStream () ؛ BufferedReader Reader = جديد BufferedReader (New InputStreamReader (inputStream ، "UTF-8")) ؛ خط السلسلة = "" ؛ نمط نمط = نمط. compile ("<a.*؟ href = [/" ']؟ ((https؟: //)؟/؟ [^/"']+) [/" ']؟ (matcher.find ()) {string newLink = matcher.group (1) .trim () ؛ NewLink ؛ ! newmap.containskey (NewLink) E.PrintStackTrace () ؛ } catch (interruptedException e) {E.PrintStackTrace () ؛ } oldmap.replace (Oldlink ، false ، true) ؛ }} // هناك رابط جديد ، تابع اجتياز if (! newmap.isempty ()) {oldmap.putall (newmap) ؛ oldmap.putall (crawllinks (oldlinkhost ، oldmap)) ؛ // بسبب خصائص الخريطة ، لن يكون هناك أزواج ذات قيمة مفتاح مكررة} إرجاع OldMap ؛ }}ثلاث نتائج الاختبار النهائي
ملاحظة: في الواقع ، فإن استخدام التكرار ليس جيدًا للغاية ، لأنه إذا كان لدى موقع الويب المزيد من الصفحات ، فسيكون استهلاك الذاكرة كبيرًا جدًا إذا كان البرنامج يعمل لفترة طويلة.
شكرا لك على القراءة ، آمل أن تساعدك. شكرا لك على دعمك لهذا الموقع!