任务需要,希望根据一组ip地址来获取其真实所在地。
忽然想起来之前使用百度的服务是可以通过ip地址查询真实地址的,于是迅速在百度的搜索页中找到了这个小工具。发现百度通过调用www.ip138.com/这个网站的服务来获取真实地址。
在输入栏输入查询按钮,并点击查询按钮,发现这个查询服务是通过ajax实现的,请求的地址是 https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=123.123.192.255&co=&resource_id=6006&t=1433922612109&ie=utf8&oe=gbk&cb=op_aladdin_callback&format=json&tn=baidu&cb=jQuery110206955700272228569_1433922418817&_=1433922418822
返回的信息数据如下:
/**/jQuery110206955700272228569_1433922418817({"status":"0","t":"1433922612109","set_cache_time":"","data":[{"location":"北京市 联通", "titlecont":"IP地址查询", "origip":"123.123.192.255", "origipquery":"123.123.192.255", "showlamp":"1", "showLikeShare":1, "shareImage":1, "ExtendedLocation":"", "OriginQuery":"123.123.192.255", "tplt":"ip", "resourceid":"6006", "fetchkey":"123.123.192.255", "appinfo":"", "role_id":0, "disp_type":0}]});
看到返回的信息,就应该发现一些有用的东西了吧。所以我们可以通过模拟向百度的服务器发送请求来获取我们想要的所在地信息
事实在之后的尝试中我发现url后的参数列表中有一部分完全用不到,于是我就删减了部分不影响结果的参数
以java语言实现
获取返回信息的方法
/** * 通过用户ip获取用户所在地 * @param userIp * @return */ public String getUserLocation(String userIp) { String url = "http://opendata.baidu.com/api.php?query=" + userIp; url += "&co=&resource_id=6006&t=1433920989928&ie=utf8&oe=gbk&format=json"; return HttpRequest.sendGet(url); }
HttpReqeuest的Get方法(使用urlConnection) 向指定的url发送get请求
public static String sendGet(String url) { String result = ""; BufferedReader in = null; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; }
在执行getUserLocation后返回的就是百度返回的json字符串了,所以也可以用一些json解析的方法来获取json中的location信息,解析的方式各有不同,不再做过多描述了。
最后需要注意的一点,这个方法本身是基于baidu提供的ip地址获取服务接口实现的,所有当百度的服务接口如果有所修改的话,这个功能是由失效的可能性的。