1.使用背景:
- 电商项目中,用户地址,订单地址使用频率会比较高.
- 多个平台的地址码表并不统一,有各自不同的标准.
- 国家统计局每年有"统计用区划代码和城乡划分代码"的统计
- 基于此,考虑用政府网站的数据作为依据,形成自己的地址码表.
数据来源: 政府网站
2.部分代码实现补充说明:
- 抓取过程中,页面乱码解决:
获取返回的HTML内容中,前边一部分字节码,获取网页配置的contentType;尝试用gbk,utf8和iso8895-1来解码,避免出现内容乱码.
代码逻辑如下:
public static String decodeHtml(byte[] first) {
try {
if( Objects.isNull(first) ){ return ""; }
if( first.length == 0 ){ return ""; }
byte[] headerBytes = new byte[256];
if( first.length < 256 ){
headerBytes = new byte[first.length];
}
System.arraycopy(first,0,headerBytes,0,headerBytes.length);
String header = new String(first,StandardCharsets.ISO_8859_1);
List<String> regexgroups = new ArrayList<>();
String regex = "content=\"text/html; charset=(iso-8859-1|iso8859-1|gb2312|GB2312|gbk|GBK|utf-8|UTF-8)\"";
filterByRegex(regex, regexgroups, header);
String charset = "charset=utf-8";
if(!CollectionUtils.isEmpty(regexgroups)){
charset = regexgroups.get(0);
}
String content = "";
if( charset.toLowerCase().contains("gb2312")){
content = new String(first,"gbk");
}
if( charset.toLowerCase().contains("gbk")){
content = new String(first,"gbk");
}
if( charset.toLowerCase().contains("utf-8")){
content = new String(first, StandardCharsets.UTF_8);
}
if( charset.toLowerCase().contains("ios8859-1")){
content = new String(first,StandardCharsets.ISO_8859_1);
}
if( charset.toLowerCase().contains("ios-8859-1")){
content = new String(first,StandardCharsets.ISO_8859_1);
}
return content;
} catch (UnsupportedEncodingException e) {
throw new BaseRuntimeException(e);
}
}
- HTML抓取过程中,使用jsoup工具包;jsoup可以非常方便的操作HTML中的dom元素;类似javascript操作dom元素一样;最新的jsoup版本,在性能上也有较大提升,小规模的抓取数据,可以尝试用jsoup,可以省很多力气.
- 常用的地址数据,包含三级即够用(京东地址包含四级,而且随时变动,如果第三方要使用京东的地址,使用效果不太好),所以实例中并没有抓取乡镇和街道地址.
- 几个直辖市的数据处理方式,也参考淘宝地址来做的.
- 最后对重庆下边的县做了特殊处理,这个是参考淘宝的地址做的处理.
- 因为国家统计局每年会更新一次地址数据,为了地址数据最新,也可以每年做一次地址数据的更新.
- 地址表中,预留了地址的坐标字段,这个在实际业务中,可能会用到.
- 码表中,香港,澳门,台湾部分的数据,请使用者自己添加,可以参考淘宝地址数据.