jsoup เป็นตัวแยกวิเคราะห์ Java HTML ที่สามารถแยกวิเคราะห์ที่อยู่ URL และเนื้อหาข้อความ HTML ได้โดยตรง มี API ที่ใช้ความพยายามต่ำมากในการดึงและจัดการข้อมูลผ่านวิธีการจัดการแบบ DOM, CSS และ jQuery
ขณะนี้ฉันกำลังดำเนินการบางอย่างที่ต้องใช้ข้อมูลระดับภูมิภาคทั่วประเทศ ตั้งแต่จังหวัดและเมือง ไปจนถึงเทศมณฑล เมือง และถนน Du Niang และการค้นหาใน Google หลายครั้งล้มเหลวในการค้นหาข้อมูลที่สมบูรณ์ ในท้ายที่สุด การทำงานหนักก็ได้ผลตอบแทน และในที่สุดฉันก็พบข้อมูลที่ค่อนข้างสมบูรณ์ อย่างไรก็ตาม ข้อมูลที่นี่มีความแม่นยำในระดับเมืองเท่านั้น และไม่มีข้อมูลในระดับหมู่บ้าน (ฉันได้เรียนรู้ในภายหลังว่าทำไมโดยการวิเคราะห์ข้อมูล แหล่งที่มา 555) นอกจากนี้ข้อมูลบางส่วนที่บล็อกเกอร์ให้มาก็ซ้ำซ้อนสำหรับฉันที่มีความผิดปกติครอบงำและแสวงหาความสมบูรณ์แบบฉันคิดว่าฉันต้องรวบรวมข้อมูลส่วนนี้ด้วยตัวเอง
เนื้อหาในบล็อกข้างบนนี้ค่อนข้างจะสมบูรณ์ ซึ่ง Blogger เองก็ใช้ PHP มาเป็นที่ 1 ในการจัดอันดับภาษาโปรแกรมในปี 2015 เราไม่สามารถแสดงจุดอ่อนได้ รวบรวมข้อมูลที่เราต้องการจากหน้าเว็บ...
ขั้นตอนแรก การเตรียมการ (แหล่งข้อมูล + เครื่องมือ):
แหล่งข้อมูล (ข้อมูลอย่างเป็นทางการที่ครอบคลุมและเชื่อถือได้มากที่สุด): http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/
เครื่องมือสำหรับการรวบรวมข้อมูล (เครื่องมือรวบรวมข้อมูล): http://jsoup.org/
ขั้นตอนที่สอง การวิเคราะห์แหล่งข้อมูล:
ก่อนอื่นฉันจะไม่อธิบายการใช้งาน jsoup tool ที่นี่ หากคุณสนใจสามารถตรวจสอบได้ด้วยตัวเอง
เมื่อทำการพัฒนา คุณควรเรียนรู้เพิ่มเติมเกี่ยวกับการใช้เครื่องมือซอฟต์แวร์บางอย่าง เมื่อคุณพบมันในกระบวนการพัฒนาปกติเท่านั้น คุณจะรู้ว่าจะเริ่มต้นจากตรงไหน ฉันขอแนะนำให้ทุกคนให้ความสำคัญกับเครื่องมือซอฟต์แวร์รอบตัวคุณมากขึ้นในกรณีที่คุณต้องการ พวกเขา. ก่อนจะทำสิ่งนี้ ฉันไม่รู้วิธีใช้ jsoup แต่ฉันรู้ว่า jsoup สามารถใช้ทำอะไรได้บ้าง เมื่อจำเป็นต้องใช้ ฉันจะหาข้อมูลและเรียนรู้ด้วยตัวเอง
แหล่งข้อมูลดังกล่าวเผยแพร่โดยสำนักงานสถิติแห่งชาติของสาธารณรัฐประชาชนจีนในปี 2013 และมีความถูกต้องแม่นยำและเชื่อถือได้
ต่อไป มาวิเคราะห์โครงสร้างของแหล่งข้อมูล โดยเริ่มจากหน้าแรก:
โดยการวิเคราะห์ซอร์สโค้ดของหน้าแรก เราจะได้สามประเด็นต่อไปนี้:
1. เลย์เอาต์ทั้งหมดของเพจถูกควบคุมโดยแท็กตาราง กล่าวคือ หากเราต้องการเลือกไฮเปอร์ลิงก์ผ่าน jsoup เราต้องใส่ใจกับข้อเท็จจริงที่ว่าในภาพด้านบน ไม่ใช่แค่ตำแหน่งที่ทำเครื่องหมายด้วย จังหวัด เมือง และภูมิภาคที่ใช้ตาราง มีหลายตารางในทั้งหน้า จึงไม่สามารถส่งผ่านตารางได้โดยตรง
เชื่อมต่อเอกสาร = เชื่อมต่อ ("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2013/");
องค์ประกอบ rowProvince = Connect.select("table");
เพื่อแยกวิเคราะห์ข้อมูล
2. มีไฮเปอร์ลิงก์กี่ตำแหน่งบนหน้าเว็บ? บางทีเจ้าหน้าที่อาจพิจารณาว่าเหตุใดโปรแกรมเมอร์เช่นคุณจำเป็นต้องได้รับข้อมูลดังกล่าว หน้าเว็บนี้สะอาดมาก ยกเว้นหมายเลขการลงทะเบียนด้านล่างซึ่งเป็นไฮเปอร์ลิงก์ที่ซ้ำซ้อน ลิงก์อื่น ๆ ก็สามารถรวบรวมข้อมูลได้โดยตรง
3. รูปแบบข้อมูลจังหวัดและเมือง แต่ละแถวของตารางที่มีข้อมูลที่ถูกต้องมีแอตทริบิวต์คลาส Provincetr แอตทริบิวต์นี้มีความสำคัญมาก โปรดอ่านต่อ มีแท็ก td หลายแท็กในแต่ละแถวของข้อมูล และแต่ละแท็ก td มีไฮเปอร์ลิงก์ . และไฮเปอร์ลิงก์นี้ก็คือไฮเปอร์ลิงก์ที่เราต้องการนั่นเอง ข้อความของไฮเปอร์ลิงก์คือชื่อของจังหวัด (เทศบาล ฯลฯ)
มาดูหน้าข้อมูลทั่วไปอีกครั้ง (หน้าข้อมูลทั่วไปประกอบด้วยหน้าแสดงข้อมูลสามระดับที่ระดับเมือง เทศมณฑล และเมือง):
เหตุผลที่เรารวมสามหน้าข้างต้นเข้าด้วยกันก็เพราะจากการวิเคราะห์ เราพบว่าหน้าข้อมูลของข้อมูลทั้งสามระดับมีความสอดคล้องกันอย่างสมบูรณ์ ข้อแตกต่างเพียงอย่างเดียวคือแอตทริบิวต์คลาสของแถวข้อมูล tr ในข้อมูลซอร์สโค้ด html ตารางไม่สอดคล้องกัน ตามลำดับ สอดคล้องกับ: citytr, countrytr และ towntr ทุกอย่างอื่นสอดคล้องกัน ด้วยวิธีนี้ เราสามารถใช้วิธีการทั่วไปในการแก้ปัญหาการรวบรวมข้อมูลของทั้งสามหน้านี้
ต่อไป มาวิเคราะห์โครงสร้างของแหล่งข้อมูล โดยเริ่มจากหน้าแรก:
สุดท้ายนี้ ให้ดูที่หน้าข้อมูลระดับหมู่บ้าน:
รูปแบบข้อมูลในระดับหมู่บ้านไม่สอดคล้องกับรูปแบบข้อมูลของเมือง อำเภอ และเมืองที่กล่าวมาข้างต้น ข้อมูลที่แสดงในระดับนี้เป็นระดับต่ำสุดจึงไม่มีการเชื่อมโยง ดังนั้น วิธีการรวบรวมข้อมูลของเมือง อำเภอ และข้อมูลเมืองข้างต้นไม่สามารถนำมาใช้ได้ การรวบรวมข้อมูล คลาสของแถวตารางที่แสดงข้อมูลที่นี่คือ Villagegetr นอกจากสองจุดนี้แล้ว ข้อมูลแต่ละแถวยังมีข้อมูลสามคอลัมน์ การจำแนกประเภทเมืองและชนบท (รูปแบบข้อมูลของเมือง มณฑล และเมืองจะแตกต่างกัน มีรายการนี้) และคอลัมน์ที่สามคือชื่อเมือง
หลังจากเข้าใจประเด็นข้างต้นแล้ว เราก็เริ่มเขียนโค้ดได้เลย
ขั้นตอนที่สาม การใช้งานการเข้ารหัส:
นำเข้า java.io.BufferedWriter; นำเข้า java.io.FileWriter; นำเข้า java.io.IOException; นำเข้า java.util.Map; org.jsoup.nodes.Document; นำเข้า org.jsoup.nodes.Element; org.jsoup.select.Elements; /** * การรวบรวมข้อมูลของจังหวัด เมือง มณฑล เมือง และหมู่บ้านทั่วประเทศ * @author liushaofeng * @date -- am:: * @version .. */ public class JsoupTest { แผนที่คงที่ส่วนตัว <Integer, String> cssMap = ใหม่ HashMap <Integer, String>(); BufferedWriter แบบคงที่ส่วนตัว bufferedWriter = null; "provincetr");// จังหวัด cssMap.put(, "citytr");// เมือง cssMap.put(, "countytr");// มณฑล cssMap.put(, "towntr");// เมือง cssMap.put (, "villagetr");//village} โมฆะสาธารณะคงหลัก (สตริง [] args) พ่น IOException { ระดับ int = ; initFile(); // รับข้อมูลจังหวัดทั่วประเทศ เชื่อมต่อเอกสาร = เชื่อมต่อ("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm//"); องค์ประกอบ rowProvince = Connect.select("tr. " + cssMap.get(level)); สำหรับ (องค์ประกอบ ProvinceElement : rowProvince)//สำรวจจังหวัดและเมืองในแต่ละแถว{ องค์ประกอบ select = ProvinceElement.select("a"); สำหรับ (องค์ประกอบจังหวัด : เลือก)//แต่ละจังหวัด (มณฑลเสฉวน) { parseNextLevel(จังหวัด, ระดับ + } } closeStream(); } ส่วนตัว void initFile() { ลอง { bufferedWriter = new BufferedWriter(new FileWriter(new File("d://CityInfo.txt"), true)); } catch (IOException e) { e.printStackTrace(); } } โมฆะคงที่ส่วนตัว closeStream() { if (bufferedWriter != null) { ลอง { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace() bufferedWriter = null; } } โมฆะคงที่ส่วนตัว parseNextLevel (องค์ประกอบ parentElement ระดับ int) พ่น IOException { ลอง { Thread.sleep();//Sleep มิฉะนั้นอาจเกิดรหัสสถานะข้อผิดพลาดต่างๆ} catch (InterruptedException e) { e.printStackTrace(); } Document doc = Connect(parentElement.attr("abs:href")); doc != null) { Elements newsHeadlines = doc.select("tr." + cssMap.get(level));// // รับแถวข้อมูลจากตารางสำหรับ (องค์ประกอบองค์ประกอบ : newsHeadlines) { printInfo(องค์ประกอบ, ระดับ + ); Elements select = element.select("a");// เมื่อเรียกซ้ำ นี่เป็นการพิจารณาว่าเป็นข้อมูลระดับหมู่บ้านหรือไม่ data ไม่มีแท็ก if (select.size() != ) { parseNextLevel(select.last(), ระดับ + ); } } } } /** * เขียนบรรทัดข้อมูลลงในไฟล์ข้อมูล* @param องค์ประกอบข้อมูลที่รวบรวมข้อมูล องค์ประกอบ* @ระดับพาราม ระดับเมือง*/ โมฆะส่วนตัวคงที่ printInfo(องค์ประกอบองค์ประกอบ ระดับ int) { ลอง { bufferedWriter.write(element.select("td").last().text() + "{" + ระดับ + "}[" + element.select("td").first().text() + "]"); bufferedWriter.newLine(); bufferedWriter.flush(); } catch (IOException e) { e.printStackTrace(); } } การเชื่อมต่อเอกสารคงที่ส่วนตัว (URL สตริง) { if (url == null || url.isEmpty()) { โยน IllegalArgumentException ใหม่ (" The input url('" + url + "') is invalid!"); } ลอง { return Jsoup.connect(url).timeout( * ).get(); } จับ (IOException e) { e.printStackTrace(); กระบวนการรวบรวมข้อมูลเป็นกระบวนการที่ใช้เวลานาน เพียงรอช้าๆ ฮ่าๆ เนื่องจากโปรแกรมใช้เวลานานในการรัน โปรดอย่าพิมพ์เอาต์พุตบนคอนโซล ไม่เช่นนั้นอาจส่งผลต่อการทำงานของโปรแกรมได้....
รูปแบบของข้อมูลสุดท้ายที่ได้รับมีดังนี้ ("{}" หมายถึงระดับเมือง และเนื้อหาใน "[]" หมายถึงรหัสเมือง):
เทศบาลตำบล {3}[110100000000]
เขตตงเฉิง{4}[110101000000]
ที่ว่าการตำบลตงหัวเหมิน{5}[110101001000]
คณะกรรมการชุมชนย่าน Duofu Lane {6}[110101001001]
คณะกรรมการย่านชุมชน Yinzha{6}[110101001002]
คณะกรรมการชุมชนย่านตงชาง{6}[110101001005]
คณะกรรมการย่านชุมชน Zhide{6}[110101001006]
คณะกรรมการชุมชนย่าน Nanchizi{6}[110101001007]
คณะกรรมการชุมชนย่านหวงตู่กัง{6}[110101001008]
คณะกรรมการชุมชนย่านเติ้งซือโข่ว{6}[110101001009]
คณะกรรมการชุมชนย่านถนนเจิ้งอี้ {6}[110101001010]
คณะกรรมการชุมชนย่านกันหยู {6}[110101001011]
คณะกรรมการย่านชุมชนไท่จีชาง{6}[110101001013]
คณะกรรมการชุมชนย่าน Shaojiu{6}[110101001014]
คณะกรรมการชุมชนย่านหวังฝูจิ่ง{6}[110101001015]
ที่ว่าการตำบลจิงซาน{5}[110101002000]
คณะกรรมการชุมชนย่านวัดหลงฝู่ {6}[110101002001]
คณะกรรมการชุมชนย่าน Jixiang {6}[110101002002]
คณะกรรมการชุมชนย่านหวงหัวเหมิน{6}[110101002003]
คณะกรรมการชุมชนย่านจงกู่{6}[110101002004]
คณะกรรมการชุมชนย่าน Weijia{6}[110101002005]
คณะกรรมการชุมชนย่านวังจือหม่า {6}[110101002006]
คณะกรรมการชุมชนย่านถนน Jingshan East {6}[110101002008]
คณะกรรมการชุมชนย่านถนน Huangcheng Genbei {6}[110101002009]
ที่ว่าการตำบลเจียวต้าโข่ว{5}[110101003000]
คณะกรรมการย่านชุมชน Jiaodong{6}[110101003001]
คณะกรรมการชุมชนย่านฟู่เซียง{6}[110101003002]
คณะกรรมการชุมชนย่านต้าซิง {6}[110101003003]
คณะกรรมการชุมชนย่าน Fuxue{6}[110101003005]
คณะกรรมการชุมชนย่านชุมชนกู่โหลวหยวน{6}[110101003007]
คณะกรรมการชุมชนย่าน Juer{6}[110101003008]
คณะกรรมการชุมชนเพื่อนบ้านหนานโหลวกู่เซียง{6}[110101003009]
ที่ว่าการตำบลอันดิงเหมิน{5}[110101004000]
คณะกรรมการชุมชนชุมชน Jiaobei Toutiao {6}[110101004001]
คณะกรรมการชุมชนย่านเป่ยโหลวกู่เซียง {6}[110101004002]
คณะกรรมการชุมชนย่าน Guozijian{6}[110101004003]
-
หลังจากได้รับข้อมูลข้างต้นแล้ว คุณสามารถรู้ได้ว่าคุณต้องการทำอะไรก็ตาม โค้ดข้างต้นสามารถเรียกใช้ได้โดยตรง หลังจากรวบรวมข้อมูลจากแหล่งข้อมูลแล้ว โค้ดดังกล่าวก็สามารถแปลงเป็นรูปแบบที่คุณต้องการได้โดยตรง