背景
最近有个需求,需要使用查询手机号归属地,进行客户地区统计分析。
思路
- 方案1
首先想到的是找第三方的api接口,直接根据手机号调用. 网上有很多,比如360的。
弊端: 这些有的收费的,有的个数限制的,而且批量查询调的确是很费劲的。 - 方案2
想到能不能找到一个手机号归属地的数据库字典,比如excel等。我们保存到自己的数据库或服务器中,去一行行解析呢。的确网上也是有这种方案的。
弊端: 自己维护数据库字典,自己写的查询效率不知如何。 - 方案3:
感谢大神们的分享精神,找到一个开源项目,他直接给把字典和查询给封装成了jar包,打到了maven中央仓库,我们只要引用jar就可以了。顺着这个思路,找到了网上有很多实现,都是基于那位大神的项目做得封装。比如java 的,go语言的,python等。
https://gitee.com/oss/phonedata?_from=gitee_search
实战
本人就基于第三种方案实现。具体看下面的方式:
1.引入jar包
<dependency> <groupId>me.ihxq.projects</groupId> <artifactId>phone-number-geo</artifactId> <version>1.0.9-202108</version> </dependency>
2.测试使用
@Test public void testPhone(){ PhoneNumberLookup phoneNumberLookup1 = new PhoneNumberLookup(); String province = phoneNumberLookup1.lookup("13565403278") .map(PhoneNumberInfo::getAttribution) .map(Attribution::getProvince) .orElse("未知"); log.info(province); PhoneNumberLookup phoneNumberLookup = new PhoneNumberLookup(); PhoneNumberInfo found = phoneNumberLookup.lookup("13565403278").orElseThrow(RuntimeException::new); found.getNumber(); // 18798896741 found.getAttribution().getProvince(); // 贵州 found.getAttribution().getCity(); // 贵阳 found.getAttribution().getZipCode(); // 550000 found.getAttribution().getAreaCode(); // 0851 found.getIsp(); // ISP.CHINA_MOBILE log.info(JSON.toJSONString(found)); }
运行结果如下:
3.项目中使用
比如我有个小需求,根据用户登录过app的手机号,进行数据大屏展示。就可以直接这样用。
/** * 1.查询当日登录过用户 * 2.基于当日登录用户的手机号,获取手机号对应的归属地 * 返回数据结果 */ @Override public List<PhoneProvinceDTO> statisticsUserMap() { //获取今日日期 String day = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); //获取今日登陆过的 所有用户手机号 List<String> todayLoginUserPhones = this.baseMapper.getTodayLoginUserPhones(day); List<PhoneProvinceDTO> list = new ArrayList<>(); todayLoginUserPhones.parallelStream().forEach(item -> { PhoneProvinceDTO phoneProvinceDTO = new PhoneProvinceDTO(); //调用手机号归属地的工具方法 PhoneNumberLookup phoneNumberLookup = new PhoneNumberLookup(); String province = phoneNumberLookup.lookup(item) .map(PhoneNumberInfo::getAttribution) .map(Attribution::getProvince) .orElse("未知"); phoneProvinceDTO.setProvince(province); list.add(phoneProvinceDTO); }); if (CollectionUtils.isEmpty(list)){ return Collections.emptyList(); } //分组统计今日登陆过的 省份人数 Map<String, List<PhoneProvinceDTO>> groupMap = list.parallelStream().collect(Collectors.groupingBy(PhoneProvinceDTO::getProvince)); //定义返回的集合对象 List<PhoneProvinceDTO> resultList = new ArrayList<>(); groupMap.forEach((k, v) -> { PhoneProvinceDTO dto = new PhoneProvinceDTO(); int size = v.size(); dto.setProvince(k); dto.setCount(size); resultList.add(dto); }); if (CollectionUtils.isEmpty(resultList)){ return Collections.emptyList(); } //重写了Comparable 进行倒序排序 Collections.sort(resultList); return resultList; }
这样就直接拿到了所有的登录人省份,进行数据分析了!!!
特别提醒
目前:这个手机号库是21年8月份更新,如果后续更新了,跟着替换下jar的版本即可。如果等不及,也可以继续找最新的手机号库源,定时同步,自己封装sprinboot-start奥,然后调用奥。大功告成,完!