jsoup هو محلل Java HTML يمكنه تحليل عنوان URL ومحتوى نص HTML مباشرةً. فهو يوفر واجهة برمجة تطبيقات منخفضة الجهد للغاية لاسترداد البيانات ومعالجتها من خلال أساليب المعالجة المشابهة لـ DOM وCSS وjQuery.
أنا أعمل حاليًا على شيء يتطلب بيانات إقليمية في جميع أنحاء البلاد، من المقاطعات والمدن إلى المقاطعات والبلدات والشوارع. فشلت عمليات بحث Du Niang المختلفة وعمليات بحث Google المختلفة في العثور على بيانات كاملة. في النهاية، أتى العمل الشاق بثماره، وعثرت أخيرًا على بيانات كاملة نسبيًا، ومع ذلك، فإن البيانات هنا دقيقة فقط على مستوى المدينة، ولا توجد بيانات على مستوى القرية (عرفت السبب لاحقًا من خلال تحليل البيانات). المصدر، هاها). بالإضافة إلى ذلك، بعض البيانات المقدمة من المدونين زائدة عن الحاجة بالنسبة لي، التي تعاني من اضطراب الوسواس القهري وتسعى إلى الكمال، اعتقدت أنه يجب علي الزحف إلى هذا الجزء من البيانات بنفسي.
المحتوى الموجود في منشور المدونة أعلاه غني جدًا. استخدم المدون PHP لتنفيذه باعتباره المركز الأول في تصنيفات لغات البرمجة في عام 2015، والآن سأأخذك لمعرفة كيفية استخدام Java نقوم بالزحف إلى البيانات التي نريدها من صفحة الويب...
الخطوة الأولى: الإعداد (مصدر البيانات + الأدوات):
مصدر البيانات (البيانات الرسمية الأكثر شمولاً وموثوقية حتى الآن): http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/
أدوات الزحف إلى البيانات (أدوات الزاحف): http://jsoup.org/
الخطوة الثانية: تحليل مصدر البيانات:
في البداية، لن أشرح استخدام أداة jsoup هنا، إذا كنت مهتمًا، يمكنك التحقق من ذلك بنفسك.
عند القيام بالتطوير، يجب أن تتعلم المزيد حول استخدام بعض الأدوات البرمجية، فقط عندما تصادفها في عملية التطوير العادية، ستعرف من أين تبدأ هم. قبل صنع هذا الشيء، لم أكن أعرف كيفية استخدام jsoup، لكنني أعرف ما يمكن استخدام jsoup من أجله، وعندما أحتاج إلى استخدامه، سأبحث عن المعلومات وأتعلم بنفسي.
تم إصدار مصدر البيانات المذكور أعلاه من قبل المكتب الوطني للإحصاء لجمهورية الصين الشعبية في عام 2013، ودقته وموثوقيته أمر بديهي.
بعد ذلك، دعونا نحلل بنية مصدر البيانات، بدءًا من الصفحة الرئيسية:
من خلال تحليل الكود المصدري للصفحة الرئيسية يمكننا الحصول على النقاط الثلاث التالية:
1. يتم التحكم في تخطيط الصفحة بالكامل من خلال علامة الجدول، وهذا يعني أنه إذا أردنا تحديد الارتباطات التشعبية من خلال jsoup، فيجب علينا الانتباه إلى حقيقة أنه في الصورة أعلاه، لم يتم وضع علامة فقط على الأماكن. بالنسبة للمقاطعات والمدن والمناطق التي تستخدم الجداول، توجد جداول متعددة في الصفحة بأكملها، لذلك لا يمكن تمرير الجدول مباشرة
اتصال الوثيقة = الاتصال("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/");
Elements RowProvince = Connect.select("table");
لتحليل البيانات.
2. ما هو عدد الأماكن التي تحتوي على روابط تشعبية في الصفحة؟ ربما يكون المسؤول قد فكر في سبب احتياج المبرمجين مثلك إلى الحصول على مثل هذه البيانات. الصفحة نظيفة للغاية، باستثناء رقم التسجيل الموجود أدناه وهو رابط تشعبي زائد عن الحاجة، ويمكن الزحف إلى الروابط الأخرى مباشرة.
3. أنماط بيانات المقاطعات والمدن. يحتوي كل صف من الجدول الذي يحتوي على معلومات صالحة على سمة فئة Provincetr. هذه السمة مهمة جدًا. أما بالنسبة لسبب أهميتها، فيرجى متابعة القراءة؛ هناك علامات td متعددة في كل صف من البيانات، وتحتوي كل علامة td على رابط تشعبي وهذا الارتباط التشعبي هو بالضبط الارتباط التشعبي الذي نريده. نص الارتباط التشعبي هو اسم المقاطعة (البلدية، وما إلى ذلك).
دعونا نلقي نظرة على صفحة البيانات العامة مرة أخرى (تتضمن صفحات البيانات العامة صفحات عرض بيانات ثلاثية المستويات على مستوى المدينة والمقاطعة والبلدة):
السبب وراء تجميع الصفحات الثلاث المذكورة أعلاه معًا هو أنه من خلال التحليل يمكننا أن نجد أن صفحات البيانات الخاصة بمستويات البيانات الثلاثة هذه متسقة تمامًا، والفرق الوحيد هو أن سمات الفئة لصف البيانات tr في بيانات كود مصدر html الجدول غير متناسق، على التوالي، مع: citytr وcountrytr وtowntr. كل شيء آخر متسق. بهذه الطريقة، يمكننا استخدام طريقة شائعة لحل مشكلة زحف البيانات لهذه الصفحات الثلاث.
بعد ذلك، دعونا نحلل بنية مصدر البيانات، بدءًا من الصفحة الرئيسية:
وأخيرًا، ألقِ نظرة على صفحة البيانات على مستوى القرية:
تنسيق البيانات على مستوى القرية غير متوافق مع تنسيق بيانات المدن والمقاطعات والبلدات المذكورة أعلاه، والبيانات الممثلة في هذا المستوى هي المستوى الأدنى، لذلك لا يوجد رابط، لذا فإن طريقة الزحف للمدينة والمقاطعة. ولا يمكن استخدام بيانات المدينة أعلاه للزحف؛ وفئة صف الجدول التي تعرض البيانات هنا هي Villagegetr. بالإضافة إلى هاتين النقطتين، يحتوي كل صف من البيانات على ثلاثة أعمدة من البيانات التصنيف الحضري والريفي (يختلف تنسيق بيانات المدن والمقاطعات والبلدات. هذا العنصر موجود)، والعمود الثالث هو اسم المدينة.
بعد فهم النقاط المذكورة أعلاه، يمكننا البدء في البرمجة.
الخطوة الثالثة، تنفيذ الترميز:
import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.util.HashMap; import java.util.Map; org.jsoup.nodes.Document; import org.jsoup.nodes.Element; org.jsoup.select.Elements; /** * الزحف إلى بيانات المقاطعات والمدن والمقاطعات والبلدات والقرى في جميع أنحاء البلاد* @author liushaofeng * @date -- am:: * @version .. */ public class JsoupTest { Private static Map<Integer, String> cssMap = new HashMap<Integer, String>(); Private static BufferedWriter bufferedWriter = null static { cssMap.put(); "provincetr");// المقاطعة cssMap.put(), "citytr");// المدينة cssMap.put(), "countytr");// County cssMap.put(), "towntr");// Town cssMap.put (, "villagetr");//village} public static void main(String[] args) throws IOException { intlevel = ; initFile(); // الحصول على معلومات المقاطعات في جميع أنحاء البلاد Document Connect = Connect("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm//"); Elements RowProvince = Connect.select("tr. " + cssMap.get(level)); for (Element ProvinceElement :rowProvince)// اجتياز المقاطعات والمدن في كل صف{ Elements Select = ProvinceElement.select("a"); for (مقاطعة العنصر: حدد)// كل مقاطعة (مقاطعة سيتشوان) { parseNextLevel(province,level + } } CloseStream() } public static void initFile() {; حاول { bufferedWriter = new BufferedWriter(new FileWriter(new File("d://CityInfo.txt"), true))); (IOException e) { e.printStackTrace(); } } public static void CloseStream() { if (bufferedWriter != null) { حاول { bufferedWriter. Close() } Catch (IOException e) { e.printStackTrace() }; bufferedWriter = null } } public static void parseNextLevel(ElementparentElement, intlevel) throws IOException {try { Thread.sleep();// السكون، وإلا فقد تحدث رموز حالة خطأ مختلفة} Catch (InterruptedException e) { e.printStackTrace() } Document doc =connect(parentElement.attr("abs:href")); doc != null) { Elements newsHeadlines = doc.select("tr." + cssMap.get(level));// // احصل على صف من البيانات من الجدول لـ (Element element : newsHeadlines) { printInfo(element,level + ); Elements Select = element.select("a");// عند الاتصال بشكل متكرر، يكون هذا لتحديد ما إذا كانت بيانات على مستوى القرية لا تحتوي البيانات على علامة if (select.size() != ) { parseNextLevel(select.last(),level + } } } } /** * اكتب سطرًا من البيانات في ملف البيانات* @param عنصر البيانات التي تم الزحف إليها عنصر* @param مستوى مستوى المدينة*/ Private static void printInfo(Element element, int Level) {try { bufferedWriter.write(element.select("td").last().text() + "{" + المستوى + "[" + element.select("td").first().text() + "]"); bufferedWriter.newLine(); bufferedWriter.flush(); } Catch (IOException e) { e.printStackTrace(); } } Private static Documentconnect(String url) { if (url == null || url.isEmpty()) { throw new IllegalArgumentException(" عنوان url للإدخال('" + url + "') غير صالح!"); } حاول { return Jsoup.connect(url).timeout( * .get(); } Catch (IOException e) { e.printStackTrace(); return null; تعد عملية الزحف إلى البيانات عملية طويلة، ما عليك سوى الانتظار ببطء، هاها، لأن تشغيل البرنامج يستغرق وقتًا طويلاً، يرجى عدم طباعة الإخراج على وحدة التحكم، وإلا فقد يؤثر ذلك على تشغيل البرنامج....
تنسيق البيانات النهائية التي تم الحصول عليها هو كما يلي ("{}" يمثل مستوى المدينة، والمحتوى الموجود في "[]" يمثل رمز المدينة):
المنطقة البلدية {3}[110100000000]
منطقة دونغتشنغ{4}[110101000000]
مكتب منطقة دونغوامين الفرعية{5}[110101001000]
لجنة الحي المجتمعي في Duofu Lane {6}[110101001001]
لجنة حي مجتمع ينزا{6}[110101001002]
لجنة حي مجتمع دونغتشانغ{6}[110101001005]
لجنة حي مجتمع Zhide{6}[110101001006]
لجنة حي مجتمع نانشيزي{6}[110101001007]
لجنة حي مجتمع هوانغتوجانغ{6}[110101001008]
لجنة حي مجتمع دنغشيكو{6}[110101001009]
لجنة الحي المجتمعي لطريق Zhengyi{6}[110101001010]
لجنة حي مجتمع جانيو{6}[110101001011]
لجنة حي مجتمع تايجيشانغ{6}[110101001013]
لجنة حي مجتمع شاوجيو{6}[110101001014]
لجنة حي مجتمع وانغفوجينغ{6}[110101001015]
مكتب منطقة جينغشان{5}[110101002000]
لجنة حي مجتمع معبد لونغفو {6}[110101002001]
لجنة حي مجتمع جيشيانغ {6}[110101002002]
لجنة حي مجتمع هوانغوامن{6}[110101002003]
لجنة حي مجتمع تشونغغو{6}[110101002004]
لجنة حي مجتمع ويجيا{6}[110101002005]
لجنة حي مجتمع وانغتشيما {6}[110101002006]
لجنة الحي المجتمعي لشارع جينغشان إيست {6}[110101002008]
لجنة الحي المجتمعي لشارع Huangcheng Genbei {6}[110101002009]
مكتب منطقة جياوداوكو الفرعية{5}[110101003000]
لجنة حي مجتمع جياودونغ{6}[110101003001]
لجنة حي مجتمع فوكسيانغ{6}[110101003002]
لجنة حي مجتمع داشينغ {6}[110101003003]
لجنة حي مجتمع فوشيو{6}[110101003005]
لجنة حي مجتمع قولويوان{6}[110101003007]
لجنة حي جوير المجتمعية {6}[110101003008]
لجنة حي مجتمع نانلوجوكسيانج{6}[110101003009]
مكتب منطقة أندينجمين{5}[110101004000]
لجنة حي مجتمع جياوبي توتياو {6}[110101004001]
لجنة حي مجتمع Beiluoguxiang{6}[110101004002]
لجنة حي مجتمع جوزيجيان{6}[110101004003]
...
بعد الحصول على البيانات المذكورة أعلاه، يمكنك تحقيق ما تريد القيام به بنفسك، ويمكن تشغيل التعليمات البرمجية أعلاه مباشرة بعد الزحف من مصدر البيانات، ويمكن تحويلها مباشرة إلى التنسيق الذي تريده.