通过IP获取地理位置

通过IP获取地理位置

IP数据库选型

1、MaxMind公司(https://www.maxmind.com/en/geoip2-cit) 提供的IP解析数据库有:GeoIP2 City Database(收费)、GeoLite2 City(免费,但2019年1月2日后其不再更新)。

其解析正确率如下:
通过IP获取地理位置_第1张图片
代码实现:

package com.cz.iptransform

import java.io.File
import java.net.InetAddress

import com.maxmind.geoip2.DatabaseReader
import com.maxmind.geoip2.model.CityResponse
import org.slf4j.LoggerFactory

import scala.collection.mutable

/**
  * @Description Convert IP to physical address
  * @Author chezhao
  * @datae 2019/2/22
  */
object IPAddress1 {
  private val logger = LoggerFactory.getLogger(IPAddress1.getClass)

  /**
    * @Description Convert IP to physical address (通过 GeoIP2 GeoLite2开源免费的数据库 解析)
    * @param ip   IP that needs to be converted
    * @param path The path to the GeoLite2-City.mmdb
    * @return map map("key","value")   map 的 value 为  中文 和 英文 拼接而成  eg: "江苏#Jiangsu"
    */
  def getAddress(ip: String, path: String): mutable.HashMap[String, Any] = {
    val map = new mutable.HashMap[String, Any]()
    val database = new File(path)
    val reader = new DatabaseReader.Builder(database).build()
    val ipAddress = InetAddress.getByName(ip)
    var response: CityResponse = null
    if (ip.substring(0, 7).equals("192.168")) {
      map.put("country", "局域网" + "#" + "juyuwang")
      map.put("province", "局域网" + "#" + "juyuwang")
      map.put("city", "局域网" + "#" + "juyuwang")
    }
    try {
      response = reader.city(ipAddress)
      val countries = response.getCountry()
      val country = countries.getNames.get("zh-CN")
      val countryE = countries.getName
      val subdivision = response.getMostSpecificSubdivision
      val province = subdivision.getNames.get("zh-CN")
      val provinceE = subdivision.getName
      val cities = response.getCity
      val city = cities.getNames.get("zh-CN")
      val cityE = cities.getName
      val location = response.getLocation
      val latitude = location.getLatitude
      val longitude = location.getLongitude
      if (country != null) {
        map.put("country", country + "#" + countryE)
      } else {
        map.put("country", "")
        logger.warn("this  " + ip + "country is null ")
      }
      if (province != null) {
        map.put("province", province + "#" + provinceE)
      } else {
        map.put("province", "")
        logger.warn("this  " + ip + "province is null ")
      }
      if (city != null) {
        map.put("city", city + "#" + cityE)
      } else {
        map.put("city", "")
        logger.warn("this  " + ip + "city is null ")
      }
      if (latitude != null) {
        map.put("latitude", latitude)
      } else {
        map.put("latitude", "")
        logger.warn("this  " + ip + "latitude is null ")
      }
      if (longitude != null) {
        map.put("this  " + ip + "longitude", longitude)
      } else {
        map.put("longitude", "")
        logger.warn("this  " + ip + "longitude is null ")
      }
    } catch {
      case ex: Exception => {
        logger.error("解析失败,该IP在database中不存在" + "this address" + ip + " is not in the database.")
      }
    }
    return map
  }

  def main(args: Array[String]): Unit = {
    val path = "F:\\GeoLite2-City.mmdb"
    val ip = "61.160.22.30"
    val map = getAddress(ip, path)
    if (map.nonEmpty) {
      val country = map.get("country").get.toString
      val province = map.get("province").get.toString
      val city = map.get("city").get.toString
      if (country.nonEmpty) {
        println("国家的中文值为: " + map.get("country").get.toString.split("#")(0))
        println("国家的英文值为: " + map.get("country").get.toString.split("#")(1))
      }
      if (province.nonEmpty) {
        println("省份的中文值为: " + map.get("province").get.toString.split("#")(0))
        println("省份的英文值为: " + map.get("province").get.toString.split("#")(1))
      }
      if (city.nonEmpty) {
        println("城市的中文值为:  " + map.get("city").get.toString.split("#")(0))
        println("城市的英文值为:  " + map.get("city").get.toString.split("#")(1))
      }
    } else {
      println("===========================")
    }
  }
}

详见:个人git:https://github.com/seniscz/toolsutil/blob/master/utilsproj/toolsutil-parent/iputil/src/main/scala/com/cz/iptransform/IPAddress1.scala

2、纯真( http://www.cz88.net/)IP数据库

纯真IP数据库是开源的IP库,支持多语言。数据库大小:9M,收集了包括中国电信、中国移动、中国联通、长城宽带、聚友宽带等 ISP 的 IP 地址数据,包括网吧数据。IP数据库每5天更新一次。纯真IP库的获取率是99%

代码实现:

package com.cz.iptransform

import com.cz.iputil.IPLocationUtil
import org.slf4j.LoggerFactory

import scala.collection.mutable

/**
  * @Description Convert IP to physical address
  * @Author chezhao
  * @datae 2019/2/22
  */
object IPAddress2 {
  private val logger = LoggerFactory.getLogger(IPAddress2.getClass)

  /**
    * @Description Convert IP to physical address (通过 纯真IP数据库 解析)
    * @param ip   IP that needs to be converted
    * @param path The path to the qqwry.dat
    * @return map("key","value")
    */
  def getAddress(ip: String, path: String): mutable.HashMap[String, String] = {
    val ipUtile = new IPLocationUtil(path)
    ipUtile.init()
    val country = ipUtile.getIPLocation(ip).getCountry()
    val province = ipUtile.getIPLocation(ip).getProvince()
    val city = ipUtile.getIPLocation(ip).getCity()
    val area = ipUtile.getIPLocation(ip).getArea()
    val address = ipUtile.getIPLocation(ip).getAddress()
    val map = new mutable.HashMap[String, String]()
    if (country != null) {
      map.put("country", country)
    } else {
      map.put("country", "")
      logger.warn("this  " + ip + "country is null ")
    }
    if (province != null) {
      map.put("province", province)
    } else {
      map.put("province", "")
      logger.warn("this  " + ip + "province is null ")
    }
    if (city != null) {
      map.put("city", city)
    } else {
      map.put("city", "")
      logger.warn("this  " + ip + "city is null ")
    }
    if (area != null) {
      map.put("area", area)
    } else {
      map.put("area", "")
      logger.warn("this  " + ip + "area is null ")
    }
    if (address != null) {
      map.put("address", address)
    } else {
      map.put("address", "")
      logger.warn("this  " + ip + "address is null ")
    }
    return map
  }

  def main(args: Array[String]): Unit = {
    val map = IPAddress2.getAddress("192.168.42.189", "F:\\qqwry.dat")
    println("country : " + map.get("country").get)
    println("province : " + map.get("province").get)
    println("city : " + map.get("city").get)
    println("area : " + map.get("area").get)
    println("address : " + map.get("address").get)
  }
}

详见:个人git:https://github.com/seniscz/toolsutil/blob/master/utilsproj/toolsutil-parent/iputil/src/main/scala/com/cz/iptransform/IPAddress2.scala

你可能感兴趣的:(utils)