当前位置:   article > 正文

根据ip地址获取城市名的几种方法

免费根据ip获取城市名

在某些场景下,可能需要用到根据ip地址获取ip所对应的城市名。

152356_dMt3_2911530.png

貌似腾讯、百度等开放接口已经失效或者免费服务接口关闭等原因,很多免费接口已不能使用,本文暂时给出如下三种方法来做:

  • 使用淘宝的开放接口
  • 使用新浪的开放接口
  • 使用MaxMind提供的GeoIp离线包

接下来,我们就一起来看看这三种方法的具体使用方法,所有的示例采用Java代码完成。

淘宝和新浪开放的api都返回JSON格式的数据。

完成淘宝和新浪api接口调用,本文使用如下的依赖包:

  1. <properties>
  2. <http-client.version>4.5.2</http-client.version>
  3. <fast-json.version>1.2.23</fast-json.version>
  4. </properties>
  5. <dependencies>
  6. <dependency>
  7. <groupId>org.apache.httpcomponents</groupId>
  8. <artifactId>httpclient</artifactId>
  9. <version>${http-client.version}</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>com.alibaba</groupId>
  13. <artifactId>fastjson</artifactId>
  14. <version>${fast-json.version}</version>
  15. </dependency>
  16. </dependencies>

使用淘宝的开放接口

接口地址

淘宝的开放接口URL格式为:

http://ip.taobao.com/service/getIpInfo.php?ip=<IP_ADDRESS>

示例:

http://ip.taobao.com/service/getIpInfo.php?ip=117.136.42.86

返回结果

  1. {
  2. "data":{
  3. "region":"北京市",
  4. "area_id":"100000",
  5. "country_id":"CN",
  6. "isp":"移动",
  7. "region_id":"110000",
  8. "ip":"117.136.42.86",
  9. "country":"中国",
  10. "city":"北京市",
  11. "isp_id":"100025",
  12. "city_id":"110100",
  13. "area":"华北",
  14. "county":"",
  15. "county_id":"-1"
  16. },
  17. "code":0
  18. }

代码示例

  1. public String getCityNameByTaoBaoAPI(String ip) {
  2. String url = "http://ip.taobao.com/service/getIpInfo.php?ip=" + ip;
  3. String cityName = "";
  4. HttpClient client = HttpClientBuilder.create().build();
  5. HttpGet request = new HttpGet(url);
  6. try {
  7. HttpResponse response = client.execute(request);
  8. int statusCode = response.getStatusLine().getStatusCode();
  9. if (statusCode == HttpStatus.SC_OK) {
  10. String strResult = EntityUtils.toString(response.getEntity());
  11. try {
  12. JSONObject jsonResult = JSON.parseObject(strResult);
  13. System.out.println(JSON.toJSONString(jsonResult, true));
  14. JSONObject dataJson = jsonResult.getJSONObject("data");
  15. cityName = dataJson.getString("city");
  16. System.out.println(JSON.toJSONString(jsonResult, true));
  17. } catch (Exception e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. } catch (ClientProtocolException e) {
  22. e.printStackTrace();
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. return cityName;
  27. }

使用新浪的开放

接口地址

新浪的开放接口URL格式为:

http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=<IP_ADDRESS>

示例:

http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=117.136.42.60

返回结果

  1. {
  2. "ret":1,
  3. "desc":"",
  4. "start":-1,
  5. "isp":"",
  6. "province":"北京",
  7. "type":"",
  8. "district":"",
  9. "end":-1,
  10. "city":"北京",
  11. "country":"中国"
  12. }

代码示例

  1. public static String getCityNameBySinaAPI(String ip) {
  2. String url = "http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip="
  3. + ip;
  4. String cityName = "";
  5. HttpClient client = HttpClientBuilder.create().build();
  6. HttpGet request = new HttpGet(url);
  7. try {
  8. HttpResponse response = client.execute(request);
  9. int statusCode = response.getStatusLine().getStatusCode();
  10. if (statusCode == HttpStatus.SC_OK) {
  11. String strResult = EntityUtils.toString(response.getEntity());
  12. try {
  13. JSONObject jsonResult = JSON.parseObject(strResult);
  14. cityName = jsonResult.getString("city");
  15. System.out.println(JSON.toJSONString(jsonResult, true));
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. } catch (ClientProtocolException e) {
  21. e.printStackTrace();
  22. } catch (IOException e) {
  23. e.printStackTrace();
  24. }
  25. return cityName;
  26. }

使用GeoLiteCity离线包

下载离线包

下载GeoLiteCity离线包,并解压到本地。

下载地址http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

163544_dg4q_2911530.png

解压缩之后,可以看到解压后的GeoLiteCity.dat文件。

准备依赖包

  1. <properties>
  2. <geoip-api.version>1.2.15</geoip-api.version>
  3. </properties>
  4. <dependencies>
  5. <dependency>
  6. <groupId>com.maxmind.geoip</groupId>
  7. <artifactId>geoip-api</artifactId>
  8. <version>${geoip-api.version}</version>
  9. </dependency>
  10. </dependencies>

代码示例

  1. import java.io.IOException;
  2. import java.net.InetAddress;
  3. import com.maxmind.geoip.Location;
  4. import com.maxmind.geoip.LookupService;
  5. public class GeoLiteCityExample {
  6. public static final String GEO_LITE_FILE_LOCATION = "D:\\ips\\GeoLiteCity.dat";
  7. public String getCityName(String ip) {
  8. try {
  9. LookupService lookupService = new LookupService(
  10. GEO_LITE_FILE_LOCATION, LookupService.GEOIP_MEMORY_CACHE);
  11. Location location = lookupService.getLocation(ip);
  12. if (location != null) {
  13. return location.city;
  14. }
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. }
  18. return "";
  19. }
  20. public String getCityName(InetAddress inetAddress) {
  21. try {
  22. LookupService lookupService = new LookupService(
  23. GEO_LITE_FILE_LOCATION, LookupService.GEOIP_MEMORY_CACHE);
  24. Location location = lookupService.getLocation(inetAddress);
  25. if (location != null) {
  26. return location.city;
  27. }
  28. } catch (IOException e) {
  29. e.printStackTrace();
  30. }
  31. return "";
  32. }
  33. }

测试代码如下:

  1. import java.net.InetAddress;
  2. import java.net.UnknownHostException;
  3. public class Main {
  4. public static void main(String[] args) {
  5. GeoLiteCityExample example = new GeoLiteCityExample();
  6. String ip = "223.95.66.34";
  7. String cityName = example.getCityName(ip);
  8. // Hangzhou
  9. System.out.println(cityName);
  10. try {
  11. InetAddress inetAddress = InetAddress.getByName(ip);
  12. cityName = example.getCityName(inetAddress);
  13. // Hangzhou
  14. System.out.println(cityName);
  15. } catch (UnknownHostException e) {
  16. e.printStackTrace();
  17. }
  18. }
  19. }

Location类说明

当拿到com.maxmind.geoip.Location类后,上述示例只是拿了一个属性city来获取城市的名称,其实还能获取更多的属性,如国家,经纬度等。

  1. package com.maxmind.geoip;
  2. public class Location {
  3. public String countryCode;
  4. public String countryName;
  5. public String region;
  6. public String city;
  7. public String postalCode;
  8. public float latitude;
  9. public float longitude;
  10. public int dma_code;
  11. public int area_code;
  12. public int metro_code;
  13. //省略其它
  14. }

有兴趣的读者,可以尝试一下~~。

至此,使用Maxmind提供的GeoLiteCity离线包,通过ip获取对应城市名的示例也完成了。

小结

本篇博文给出了三个方法用于获取IP对应的城市名称使用淘宝开放API、使用新浪开放API和使用MaxMind提供的离线包

从体验上来看,

新浪接口返回结果还是挺快的。淘宝的接口可能做了连续访问的限制,有时候没有正常返回结果。

使用离线包的方式更加稳定,但是,返回结果是拼音。有些城市拼音一样,如果要进一步确定中文城市名,需要做些额外的操作来保证。

(打算写个多线程程序,将离线包中的中国城市IP信息存放到数据库中去,以后结合缓存加快处理 ~~)

今天就写到这吧

大家如果有其它不错的方式-- 获取IP地址对应的城市名称,也请留言,一起分享,谢谢。

转载于:https://my.oschina.net/wangmengjun/blog/815697

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/692254
推荐阅读
相关标签
  

闽ICP备14008679号