开发系统时经常要用到中国行政区划分数据,特别是做电商系统中的管理收货地址功能。以前通过爬百度地图数据制作的行政区域只支持三级,今天尝试爬京东的数据,支持省市县乡四级区域。
为什么爬京东的数据?原因很简单:京东做这么大了,这一块基础数据应该很全很成熟了。这个纯粹是抓数据,原理很简单不多说,直接上代码。
一、创建数据库表
首先要创建一个数据库表(t_area),本人使用的是mysql,表结构如下:
二、代码实现
以下是抓取数据的java代码:
/**
* Title: AreaUtil.java
* Description:
* Copyright: Copyright (c) 2013-2015 luoxudong.com
* Company: 个人
* Author: 罗旭东 (hi@luoxudong.com)
* Date: 2018年6月23日 上午18:24:24
* Version: 1.0
*/
package com.luoxudong.plug.shop.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.luoxudong.core.utils.NetworkUtil;
/**
* <pre>
* ClassName: AreaUtil
* Description:TODO(这里用一句话描述这个类的作用)
* Create by: 罗旭东
* Date: 2018年6月23日 上午18:24:24
* </pre>
*/
public class AreaUtil {
/** 获取地区api */
private static final String URL_JD_AREA = "https://d.jd.com/area/get?fid=%d";
/** 初始化省份数据 */
private static final String[] TABLE_PROVINCE = new String[]{
"1","北京",
"2","上海",
"3","天津",
"4","重庆",
"5","河北",
"6","山西",
"7","河南",
"8","辽宁",
"9","吉林",
"10","黑龙江",
"11","内蒙古",
"12","江苏",
"13","山东",
"14","安徽",
"15","浙江",
"16","福建",
"17","湖北",
"18","湖南",
"19","广东",
"20","广西",
"21","江西",
"22","四川",
"23","海南",
"24","贵州",
"25","云南",
"26","西藏",
"27","陕西",
"28","甘肃",
"29","青海",
"30","宁夏",
"31","新疆",
"32","台湾",
"42","香港",
"43","澳门",
"84","钓鱼岛"
};
/**
* 初始化省份数据
* @param conn
*/
public static void initArea() {
try {
Connection conn = getConn("127.0.0.1", "3306", "数据库名", "数据库用户名", "数据库密码");
for (int nIndex = 0; nIndex < TABLE_PROVINCE.length; nIndex = nIndex + 2) {
int id = Integer.parseInt(TABLE_PROVINCE[nIndex]);
String name = TABLE_PROVINCE[nIndex + 1];
try {
Statement stat = conn.createStatement();
String sql = "INSERT INTO t_area VALUES (" + id + ", '" + name + "',0, 0)";
stat.execute(sql);
stat.close();
initChildArea(conn, id, 1);
} catch (SQLException e) {
e.printStackTrace();
}
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取各省下级地区
* @param conn 数据库连接对象
* @param parentId 所属地区ID
* @param level 地区层级,省级:0,市级:1,...
*/
public static void initChildArea(Connection conn, int parentId, int level) {
String url = String.format(URL_JD_AREA, parentId);
String text = NetworkUtil.getData(url);
if (!StringUtils.isEmpty(text)) {
JSONArray array = JSON.parseArray(text);
if (array != null && array.size() > 0) {
for (int nIndex = 0; nIndex < array.size(); nIndex++) {
JSONObject object = array.getJSONObject(nIndex);
int id = object.getInteger("id");
String name = object.getString("name");
try {
Statement stat = conn.createStatement();
String sql = "INSERT INTO t_area VALUES (" + id + ", '" + name + "'," + parentId + ", " + level + ")";
stat.execute(sql);
stat.close();
initChildArea(conn, id, level + 1);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 链接数据库
* @param dbHost 数据库主机地址
* @param dbPort 数据库端口
* @param dbName 数据库名称
* @param dbUser 数据库用户名称
* @param dbPassword 数据库登录密码
* @return
* @throws Exception
*/
public static Connection getConn(String dbHost, String dbPort, String dbName, String dbUser, String dbPassword) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.jdbc.Driver").newInstance();
String connStr = "jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName
+ "?user=" + dbUser + "&password=" + dbPassword
+ "&characterEncoding=utf8";
Connection conn = DriverManager.getConnection(connStr);
return conn;
}
public static void main(String[] args) {
initArea();
}
}
三、其他
以上哪里写的不对或者有待改进,欢迎大家提意见,谢谢!
采集数据下载地址(更新与2018年6月):https://hx.rqba.com/211.html
转载请注明出处:JAVA采集京东的全国行政区划数据 - 东哥小站