首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

使用 Jsoup 爬取國家統計局全國行政區劃代碼

     編輯:Java 綜合教學

使用 Jsoup 爬取國家統計局全國行政區劃代碼

專案中需要權威的全國行政區劃數據,國家統計局提供的數據更新至 2014 年 10 月 31 日,較為完整。查詢頁面為 https://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2014/index.html。經分析,頁面結構清晰,所有區劃信息集中在一個 table.provincetable 中,適合用 Jsoup 解析。

頁面結構特點

  • 一級區劃(省級)數據從第 4 個 tr 開始,其餘層級從第 2 個 tr 開始;
  • 不同層級 tr 的 class 不同;
  • 最後一級(街道/村)及市轄區的 td 子元素結構不一致。

樹形遞歸抓取思路

將全國區劃視為一棵樹:中國為根節點,每個節點包含名稱、代碼、子節點列表及下一級頁面 URL。通過遞歸遍歷:

  1. PageFetcher 根據 URL 抓取頁面;
  2. ContentParser 解析頁面生成子節點列表;
  3. 將子節點掛載到父節點,遞歸處理每個子節點;
  4. 遇到葉子節點(URL 為空且代碼第 7-10 位為 000000)終止遞歸。
public void loadRegionNode(RegionNode regionNode, String superUrl) {
    String url = subUrl(superUrl) + regionNode.getUrl();
    FetchedPage fetchedPage = pageFetcher.getContentFromUrl(url);
    List<RegionNode> list = (regionNode.getChildNode() == null)
        ? contentParser.parseHTML(fetchedPage)
        : regionNode.getChildNode();

    if (list != null && !list.isEmpty()) {
        regionNode.setChildNode(list);
        for (RegionNode node : list) {
            if (node.getUrl() == null && !node.getId().substring(6, 12).equals("000000")) {
                break; // 葉子節點
            }
            loadRegionNode(node, url);
        }
    }
}

分層解析策略

根據 tr 子元素數量判斷節點類型:

  • 3 個子元素:無下級的市轄區;
  • 4 個子元素:葉子節點(街道/村);
  • 其他:包含下級鏈接的普通節點,提取 href、代碼、名稱。
public static List<RegionNode> parseHTML(FetchedPage page) {
    if (page == null || page.getStatusCode() != 200) return null;
    List<RegionNode> list = new ArrayList<>();
    Document doc = Jsoup.parse(page.getContent());
    Element table = doc.getElementsByTag("TABLE").get(4);
    Elements trs = table.getElementsByTag("tr");

    for (int i = 1; i < trs.size(); i++) {
        Element tr = trs.get(i);
        Elements els = tr.getAllElements();
        RegionNode node = new RegionNode();

        if (els.size() == 3) { // 無下級市轄區
            node.setId(els.get(1).text());
            node.setRegionName(els.get(2).text());
        } else if (els.size() == 4) { // 葉子節點
            node.setId(els.get(1).text());
            node.setRegionName(els.get(3).text());
        } else { // 普通節點
            node.setId(els.get(2).text());
            node.setRegionName(els.get(4).text());
            node.setUrl(els.get(2).attr("href"));
        }
        list.add(node);
    }
    return list;
}

約一小時可抓取完整樹形結構,結果可序列化為 JSON/XML 或入庫。完整源碼已上傳 GitHub:regionSpider。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved