IP地址分布分析(国内)

IP地址分布分析(国内)

四月 02, 2020 阅读量

IP地址分布分析(国内)

因为工作的原因,简单整理了一下,效率极低,娱乐用

ip所在地来源

因为第一次做这个,没弄数据库和根据ip段来判断,直接请求ip.cn,通过jsoup来获取页面数据。发现GeoIP数据不是很准确,基本以页面所在地理位置的数据为准,在获取不到准确数据的情况下参考页面GeoIP数据。
请求是最影响效率的地方,基本每秒请求一次,偶尔会报错(超时,520之类),毕竟是免费的。实际上分析的时候用的多线程(500条为一组),把没获取全的数据单独执行获取,然后在Excel表格里手动修改错误数据,然后整理计算。

代码

后来(工作完成后)根据获取数据的规律,简单写了下(渣)代码,基本就是读取ip,获取ip所在省份,ip所在省份加一。执行错误,或者有无法识别的IP(国外,本地,特殊IP等)需要手动判断。

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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
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.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

public class IpDistributionCreater {

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);

Map<String, Integer> provinceGeoIpMap = new HashMap<String, Integer>();
provinceGeoIpMap.put("Beijing", 0);
provinceGeoIpMap.put("Tianjin", 0);
provinceGeoIpMap.put("Shanghai", 0);
provinceGeoIpMap.put("Chongqing", 0);
provinceGeoIpMap.put("Hebei", 0);
provinceGeoIpMap.put("Hainan", 0);
provinceGeoIpMap.put("Yunnan", 0);
provinceGeoIpMap.put("Liaoning", 0);
provinceGeoIpMap.put("Heilongjiang", 0);
provinceGeoIpMap.put("Hunan", 0);
provinceGeoIpMap.put("Anhui", 0);
provinceGeoIpMap.put("Shandong", 0);
provinceGeoIpMap.put("Xinjiang", 0);
provinceGeoIpMap.put("Jiangsu", 0);
provinceGeoIpMap.put("Zhejiang", 0);
provinceGeoIpMap.put("Jiangxi", 0);
provinceGeoIpMap.put("Hubei", 0);
provinceGeoIpMap.put("Guangxi", 0);
provinceGeoIpMap.put("Gansu", 0);
provinceGeoIpMap.put("Shanxi", 0); // 山西
provinceGeoIpMap.put("Inner Mongolia Autonomous Region", 0);
provinceGeoIpMap.put("Shaanxi", 0); // 陕西
provinceGeoIpMap.put("Jilin", 0);
provinceGeoIpMap.put("Fujian", 0);
provinceGeoIpMap.put("Guizhou", 0);
provinceGeoIpMap.put("Guangdong", 0);
provinceGeoIpMap.put("Qinghai", 0);
provinceGeoIpMap.put("Tibet", 0); // 西藏
provinceGeoIpMap.put("Sichuan", 0);
provinceGeoIpMap.put("Ningxia Hui Autonomous Region", 0);
provinceGeoIpMap.put("Hainan", 0);

StringBuffer other = new StringBuffer();

try {

for (int i = 0; i < ips.length; i++) {
// 获取ip.cn的页面内容
Document html = httpGet("https://ip.cn/?ip=" + ips[i], null);
Elements pelements = html.getElementsByClass("well").get(0).getElementsByTag("p");
// 所在地理位置
String addresStr = pelements.get(1).getElementsByTag("code").text();
String provinceAddresStr = addresStr.substring(0, 2);
// GeoIP(局域网以及特殊ip没有)
String geoIpStr = pelements.size() == 3 ? pelements.get(2).getElementsByTag("code").text() : "";
String[] geoIpAry = geoIpStr.split(", ");
String provinceGeoIpStr = 1 < geoIpAry.length ? geoIpAry[geoIpAry.length - 2]
: 0 < geoIpAry.length ? geoIpAry[0] : "";

System.out.println(i + "\t" + provinceAddresStr + "\t" + provinceGeoIpStr);
// 根据所在地理位置判断
if (provinceMap.get(provinceAddresStr) == null) {
// 根据GeoIP判断
if (provinceGeoIpMap.get(provinceGeoIpStr) == null) {
// 其他
provinceMap.put("其他", provinceMap.get("其他") + 1);
other.append(i + "\t" + ips[i] + "\t" + addresStr + "\t" + geoIpStr + "\r\n");
} else {
provinceGeoIpMap.put(provinceGeoIpStr, provinceGeoIpMap.get(provinceGeoIpStr) + 1);
}
} else {
provinceMap.put(provinceAddresStr, provinceMap.get(provinceAddresStr) + 1);
}
}

} catch (SocketException se) {
System.out.println("连接超时,请从最后的下标继续执行,然后手动合并数据。");
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
margeCount(provinceMap, provinceGeoIpMap);
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);
// 保存其他数据
FileOutputStream fos = new FileOutputStream(new File("D:\\otherIP.txt"));
fos.write(other.toString().getBytes());
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* httGet请求
*/
private static Document httpGet(String url, String cookie) throws IOException {
Connection con = Jsoup.connect(url);
// 请求头设置
con.header("Accept", "*/*");
con.header("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36");
if (StringUtils.isNotEmpty(cookie)) {
// cookie设置
con.header("Cookie", cookie);
}
return con.get();
}

/**
* 数据合并
*/
private static void margeCount(Map<String, Integer> targetMap, Map<String, Integer> addMap) {
targetMap.put("北京", targetMap.get("北京") + addMap.get("Beijing"));
targetMap.put("天津", targetMap.get("天津") + addMap.get("Tianjin"));
targetMap.put("上海", targetMap.get("上海") + addMap.get("Shanghai"));
targetMap.put("重庆", targetMap.get("重庆") + addMap.get("Chongqing"));
targetMap.put("河北", targetMap.get("河北") + addMap.get("Hebei"));
targetMap.put("河南", targetMap.get("河南") + addMap.get("Hainan"));
targetMap.put("云南", targetMap.get("云南") + addMap.get("Yunnan"));
targetMap.put("辽宁", targetMap.get("辽宁") + addMap.get("Liaoning"));
targetMap.put("黑龙江", targetMap.get("黑龙") + addMap.get("Heilongjiang"));
targetMap.remove("黑龙");
targetMap.put("湖南", targetMap.get("湖南") + addMap.get("Hunan"));
targetMap.put("安徽", targetMap.get("安徽") + addMap.get("Anhui"));
targetMap.put("山东", targetMap.get("山东") + addMap.get("Shandong"));
targetMap.put("新疆", targetMap.get("新疆") + addMap.get("Xinjiang"));
targetMap.put("江苏", targetMap.get("江苏") + addMap.get("Jiangsu"));
targetMap.put("浙江", targetMap.get("浙江") + addMap.get("Zhejiang"));
targetMap.put("江西", targetMap.get("江西") + addMap.get("Jiangxi"));
targetMap.put("湖北", targetMap.get("湖北") + addMap.get("Hubei"));
targetMap.put("广西", targetMap.get("广西") + addMap.get("Guangxi"));
targetMap.put("甘肃", targetMap.get("甘肃") + addMap.get("Gansu"));
targetMap.put("山西", targetMap.get("山西") + addMap.get("Shanxi"));
targetMap.put("内蒙古", targetMap.get("内蒙") + addMap.get("Inner Mongolia Autonomous Region"));
targetMap.remove("内蒙");
targetMap.put("陕西", targetMap.get("陕西") + addMap.get("Shaanxi"));
targetMap.put("吉林", targetMap.get("吉林") + addMap.get("Jilin"));
targetMap.put("福建", targetMap.get("福建") + addMap.get("Fujian"));
targetMap.put("贵州", targetMap.get("贵州") + addMap.get("Guizhou"));
targetMap.put("广东", targetMap.get("广东") + addMap.get("Guangdong"));
targetMap.put("青海", targetMap.get("青海") + addMap.get("Qinghai"));
targetMap.put("西藏", targetMap.get("西藏") + addMap.get("Tibet"));
targetMap.put("四川", targetMap.get("四川") + addMap.get("Sichuan"));
targetMap.put("宁夏", targetMap.get("宁夏") + addMap.get("Ningxia Hui Autonomous Region"));
targetMap.put("海南", targetMap.get("海南") + addMap.get("Hainan"));
}
}

根据生成的文本替换Echart的数据,展示效果如下。

IP地址分布地图Echarts代码页面


IP地址分布饼状图Echarts代码页面