IP地址分布分析(国内)·续

IP地址分布分析(国内)·续

四月 17, 2020 阅读量

IP地址分布分析(国内)·续

今天和同事探讨了准确性的问题,觉得地图工具的IP地址判断最为准确,于是改写了原来的程序。因为是调用API,效率大幅提升,工作可用

ip所在地来源

因为之前写足迹用的百度地图,最开始考虑用百度地图的普通ip定位,但是免费的配合太少,每天只有1K,10QPS,秒秒钟用完。不过百度地图对于之前通过Jsoup请求的,通过GeoIP来判断的也能识别,但是对港澳台的ip地址判断不是很好,缺失太严重。后来改用高德地图的ip定位,个人用户每天30W,200QPS,够用。但是通过GeoIP来判断的识别不了,偶尔请求超时。

代码

基本和原来一样,只是把通过Jsoup获取页面内容改成调用API获取Json内容,(渣)代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;

public class IpDistributionCreaterByMap {

public static void main(String args[]) {
// String[] ips = { "116.116.91.150", // 正常内蒙古
// "127.0.0.1", // 本地
// "172.58.22.176", // 美国
// "223.104.212.147", // geoip上海
// "223.104.148.122", // geoip江苏
// "47.75.7.133" }; // 正常香港
// ipDistributionCreater(ips);

// 数据量大时从文件读取
List<String> ipList = new ArrayList<String>();
try {
BufferedReader br = new BufferedReader(new FileReader("D:\\ips.txt"));
String lineStr = "";
while ((lineStr = br.readLine()) != null) {
ipList.add(lineStr);
}
System.out.println("读取" + ipList.size() + "条IP");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
String[] ips = {};
ipDistributionCreater(ipList.toArray(ips));

}

public static void ipDistributionCreater(String ips[]) {
Map<String, Integer> provinceMap = new LinkedHashMap<String, Integer>();
provinceMap.put("北京", 0);
provinceMap.put("天津", 0);
provinceMap.put("上海", 0);
provinceMap.put("重庆", 0);
provinceMap.put("河北", 0);
provinceMap.put("河南", 0);
provinceMap.put("云南", 0);
provinceMap.put("辽宁", 0);
provinceMap.put("黑龙", 0);
provinceMap.put("黑龙江", 0);
provinceMap.put("湖南", 0);
provinceMap.put("安徽", 0);
provinceMap.put("山东", 0);
provinceMap.put("新疆", 0);
provinceMap.put("江苏", 0);
provinceMap.put("浙江", 0);
provinceMap.put("江西", 0);
provinceMap.put("湖北", 0);
provinceMap.put("广西", 0);
provinceMap.put("甘肃", 0);
provinceMap.put("山西", 0);
provinceMap.put("内蒙", 0);
provinceMap.put("内蒙古", 0);
provinceMap.put("陕西", 0);
provinceMap.put("吉林", 0);
provinceMap.put("福建", 0);
provinceMap.put("贵州", 0);
provinceMap.put("广东", 0);
provinceMap.put("青海", 0);
provinceMap.put("西藏", 0);
provinceMap.put("四川", 0);
provinceMap.put("宁夏", 0);
provinceMap.put("海南", 0);
provinceMap.put("台湾", 0);
provinceMap.put("香港", 0);
provinceMap.put("澳门", 0);
provinceMap.put("其他", 0);

StringBuffer other = new StringBuffer();

try {
for (int i = 0; i < ips.length; i++) {
// JSONObject jsonObject = httpRequest(
// "http://api.map.baidu.com/location/ip?ak=百度key&ip=" + ips[i], "GET",
// null);
// if ("0".equals(jsonObject.getString("status"))) {
// System.out.println(jsonObject.getJSONObject("content").getJSONObject("address_detail").getString("province"));
// } else {
// System.out.println("error:" + ips[i]);
// }
JSONObject jsonObject = httpRequest(
"http://restapi.amap.com/v3/ip?key=高德key&ip=" + ips[i], "GET", null);
String province = "";
if ("1".equals(jsonObject.getString("status"))) {
province = jsonObject.getString("province").substring(0, 2);
if ("[]".equals(province)) {
provinceMap.put("其他", provinceMap.get("其他") + 1);
other.append(i + "\t" + ips[i] + "\r\n");
} else {
provinceMap.put(province, provinceMap.get(province) + 1);
}
}
System.out.println(i + "\t" + province);
}

} catch (Exception e) {
e.printStackTrace();
} finally {
provinceMap.put("黑龙江", provinceMap.get("黑龙"));
provinceMap.remove("黑龙");
provinceMap.put("内蒙古", provinceMap.get("内蒙"));
provinceMap.remove("内蒙");
StringBuffer result = new StringBuffer();
provinceMap.forEach((k, v) -> {
result.append("{name: '").append(k).append("',value: ").append(v).append("},");
});
System.out.println(result.toString());
System.out.println(other);
try {
// 保存其他数据
FileOutputStream fos = new FileOutputStream(new File("D:\\otherIP.txt"));
fos.write(other.toString().getBytes());
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

/**
* 发起http请求并获取结果
*
* @param requestUrl 请求地址
* @param requestMethod 请求方式(GET、POST)
* @param outputStr 提交的数据
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
*/
public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
InputStream inputStream = null;
try {
URL url = new URL(requestUrl);
HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
// 设置请求方式(GET/POST)
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();

// 当有数据需要提交时
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
// 注意编码格式,防止中文乱码
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
// 将返回的输入流转换成字符串
inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
// 释放资源
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.parseObject(buffer.toString());
} catch (ConnectException ce) {
ce.printStackTrace();
System.out.println("server connection timed out");
} catch (Exception e) {
e.printStackTrace();
System.out.println("http request error:{}");
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return jsonObject;
}
}

根据生成的文本替换Echart的数据,这里没有全部跑完所以没做展示,可以参考之前的文章-IP地址分布分析(国内)