解决方案

利用纯真ip库搭建ip查询服务

seo靠我 2023-09-25 10:45:25

前言: 前段时间听过了纯真ip数据库,只知道是一个qqwry.dat文件,里面有一些网友收集的数据,可以用来查询ip的大致位置,即ip定位。正好,我最近在一个项目里面看到了这个数据库,它就是将qqwrSEO靠我y.dat集成到springboot项目里面,做成一个查询服务来使用的。所以,我也想来试试,但是我不是直接使用qqwry.dat这个文件。我换一种方式,我才用将qqwry.dat中的ip数据导入mysSEO靠我ql数据库中,通过数据库的查询来提供ip位置查询功能。

gitee代码地址: 纯真ip库服务搭建

基本介绍

纯真ip数据库

纯真数据库收集了包括中国电信、中国移动、中国联通、长城宽带、聚友宽带等 ISP 的 SEO靠我IP 地址数据,包括网吧数据。希望能够通过大家的共同努力打造一个没有未知数据,没有错误数据的QQ IP。IP数据库每5天更新快速,请大家定期更新IP数据库!

因为IP地址数据是民间收集的,各运营商也会不SEO靠我时的更改IP段,所以有点遗漏、错误是难免的。随数据库附送IP解压,查询软件。假如发现IP地址有不对的,或想提供新的IP地址,请到纯真IP小秘书提供IP地址数据,或者登陆纯真时空论坛“电脑板块”中的“代SEO靠我理及IP板”块告诉我们。以便及时更新IP数据库。谢谢!

这个数据库目前2020.12月版本的含有52万+条ip数据。包括了0.0.0.0-255.255.255.255的所有ip,但是我们都知道ipv4SEO靠我地址总数是:2^32,大概42亿多条。所以,这里的52多万条只是一部分,它是按照ip地址段来区分的,可以这样来理解:把0.0.0.0-255.255.255.255想象成坐标轴上一个长度为42亿的区间SEO靠我,然后分成52万份(ip段),每一份属于一个地区。 它的作用就算是这个,通过ip知道此ip属于哪个地区(当然了,精度不是太高,不适合于精确定位。)

注意:

1.一个ip段是连续的,包括一个ip段起始地址和一SEO靠我个ip段结束地址。

2.纯真数据库对于国外的ip地址,只能定位到国家,对于国内的ip地址是可以有省市县的,毕竟主要收集的还是国内的地址。

关于ip定位的精度:

因为ip地址(发达国家就占据了大部分了)不够用SEO靠我,所以它实际上是动态分配的,所以一个人的ip一直都会变化的,但是在一段时间内是不变的(政府、学校、公司等机构会具有固定的ip,个人一般没有这个权力),所以定位精度不是很好,但是如果你在国内发现某个人的SEO靠我ip地址在国外,这并不是数据出了问题,而是因为他的ip地址基本就是在国外。但是,ip地址的分配记录是保存下来的,如果有法律权限是可以查看的,因此上网需要规范言行,互联网不是法外之地,举头三尺有神明!

SEO靠我何使用我们的ip地址必在0.0.0.0-255.255.255.255之间(这里不考虑ipv6的地址),所以只要判断某个ip是否在ipstart和ipend之间就行了(即一个ip段内),就知道它属于哪SEO靠我里了。

sql查询方式即为:

注:INET_ATON函数 会将一个有效的ip地址转成整数,所以不用自己手动转换ip地址了,直接传递点分式ip地址就行了。

但是不推荐这样使用,前面那种方式是直接将ip转为整数SEO靠我存入数据库,下面这种方式是直接存入ip的点分式,然后查询时转换。这样的话,速度非常慢,因为它相当于要对每一个ip地址做转换才能查询,这是错误的使用方式。

数据准备

首先,需要准备qqwry.dat这个文件SEO靠我,因为数据在它里面。但是,我发现了一个更好用的软件,这里就不直接使用这个文件了。

注意:鉴于网络上面资源下载容易踩坑,这里推荐到这个网站去下载,点击页面中的下载即可。如果有能力的话,也可以选择捐助作者。SEO靠我

下载完成之后,解压安装这个软件,就可以使用ip查询了。但是它是一个桌面软件,我们这里的目的是做成web服务,即像这个网站一样的查询服务。这样的ip查询服务有很多,但是如果使用量大的话,自己搭建一个还是SEO靠我非常好的,成本低、可靠!并且,这个数据库是一直在更新的,而且更新频率也还高,说明它的效果还是很好的。

测试一下,结果同上面的web页面这里我们不直接使用这个软件,而是使用它的一个功能,在主界面上有一个解SEO靠我压按钮,点击将ip数据导出成文本(我这里命名成qqwry.txt)。

qqwry.txt的内容格式如下

因为这个qqwry.txt的格式,直接在数据库中查询不方便,所以需要处理一下,它目前的格式是:4列(SEO靠我ip段起始地址 ip段结束地址 area地区 location位置)。

如果直接将它们存入数据库中,那么查询就会变得麻烦,而且基本上也无法使用索引了,对于性能影响很大。这里我们采用网上别人的方式,将ipSEO靠我起始地址和ip结束地址转成数字。

所以需要先使用程序对上面的文本数据进行处理一下,我看别人的博客处理数据都是基于php的,但是我并不会世界上最好的语言,所以我就采用java来处理了。

注意:由于java语SEO靠我言没有无符号数的概念,所以ip地址并不能转成java的int型。ipv4地址是32位,int型也是32位,但是java的int中第一位是符号位,所以实际可以表示的大小是其它语言中int的一半。这也导致SEO靠我了,如果将ip地址转换为int的话,会有许多数据溢出,变成负数,所以这里需要将ip地址转成long型。

数据处理

数据处理代码

package re;import java.io.IOException; SEO靠我 import java.nio.charset.StandardCharsets; import java.nio.file.Files; importSEO靠我 java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOpSEO靠我tion; import java.util.List; import java.util.stream.Collectors;public class IPRecorSEO靠我d {private static final String regex = "\\s+";private static final int limit = 4; // split方法的这个参数的作用SEO靠我很值得深入学习一下private static final String ipRegex = "\\.";private static class Record {String ipStartStr;SEO靠我String ipEndStr;long ipStart;long ipEnd;String area;String location;public Record(String[] record) {SEO靠我this.ipStartStr = record[0];this.ipEndStr = record[1];this.ipStart = ip2Long(record[0]); // 将ip地址字符串SEO靠我转换成longthis.ipEnd = ip2Long(record[1]); // 将ip地址字符串转换成longthis.area = record[2];this.location = recoSEO靠我rd[3];}@Overridepublic String toString() {return ipStart + "," + ipEnd + "," + area + "," + locationSEO靠我 + "," + ipStartStr + "," + ipEndStr; // 转成csv格式}public String toRedis() {return "ZADD\tqqwry\t" + iSEO靠我pEnd + "\t" + "{\"ipstart\":" + ipStart + ",\"ipend\":" + ipEnd+ ",\"area\":" + "\"" + area + "\""+ SEO靠我",\"location\":" + "\"" + location + "\""+ ",\"ipstartstr\":" + "\"" + ipStartStr + "\""+ ",\"ipstarSEO靠我tend\":" + "\"" + ipEndStr+ "\"}";}}public static void main(String[] args) throws IOException {// qqSEO靠我wry.tx 的文件路径Path path = Paths.get("C:/Users/Alfred/Desktop/data/test/qqwry.txt");// 使用指定字符集(UTF-8)读取SEO靠我文件List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);// 输出测试,注意不要省略 limit,因为总共有 5SEO靠我2万+行数据,直接输出的话,压力比较大。 // lines.stream().map(IPRecord::split).limit(10).map(Record::toJson).foSEO靠我rEach(System.out::println);// 将文件转为csv文件存放long start = System.currentTimeMillis();lines = lines.streSEO靠我am().map(IPRecord::split).map(Record::toString).limit(528129) // 有效数据行数,剩下的是一些空行和最后的统计信息.collect(ColSEO靠我lectors.toList());// String csvHeader = "ipstart,ipend, area, location, ipstartstr, ipendstr\n"; SEO靠我 // Files.write(Paths.get("C:/Users/Alfred/Desktop/data/test/qqwry.csv"), csvHeader.getBytes(), SEO靠我StandardOpenOption.CREATE); //写入csv文件的头部Files.write(Paths.get("C:/Users/Alfred/Desktop/data/test/qqwSEO靠我ry_redis.csv"), lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE); //写入csv文件的主体部分System.out.SEO靠我println("Execute Success! Time: " + (System.currentTimeMillis()-start) + " ms");}public static RecorSEO靠我d split(String record) {return new Record(record.split(regex, limit));}/*** int类型是32位的,但是无法直接将ip和intSEO靠我类型进行转换,因为可能会溢出。* int类型是有符号的,除非这里有无符号整型,但是Java是没有这个的,所以* 这里需要转换成long型。* */public static long ip2Long(SEO靠我String ip) {String[] strs = ip.split(ipRegex);int[] bs = new int[4];for (int i = 0; i < 4; i++) {bs[SEO靠我i] = Integer.parseInt(strs[i]); // Byte.parseByte(strs[i]); 这个方法转成的字节范围是 -128-127,真是太坑了!}return ((bsSEO靠我[3] & 0xFFL) ) + // 这个转换方法是从jdk源码里面偷来的,挺好用的!((bs[2] & 0xFFL) << 8) +((bs[1] & 0xFFL) << 16) +((bs[0]SEO靠我 & 0xFFL) << 24);} }// 默认的split(regex)方法会以split(regex,0)调用 // 当limit N 大于0时,会匹配N-1次,SEO靠我数组长度最大为N,返回数组的最后一个元素会把数组最后的所有字符包括进来 // 当limit N 小于0时,会匹配尽可能多次,返回最大长度的数组 // 当limit N SEO靠我等于0时,会匹配尽可能多次,返回最大长度的数组,并且末尾的空串不会包含进来//推荐使用正则表达式,速度飞起 //String record = "0.0.0.0 0.255.255.2SEO靠我55 IANA 保留地址"; //String regex = "\\s+"; //long start = System.currentTimeMillis(); SEO靠我 //for (String s : record.split(regex)) { // System.out.println(s); //} SEO靠我 //System.out.println(System.currentTimeMillis()-start);//这种方式太慢了,简直难以忍受! //List<String> stSEO靠我rList = new ArrayList<>(); //boolean flag = true; //StringBuilder sb = new StringBuiSEO靠我lder(); // //char[] chs = record.toCharArray(); //for (int i = 0; i < chs.leSEO靠我ngth; i++) { // if (chs[i] != ) { // sb.append(chs[i]); // if (i == chs.lengSEO靠我th - 1) { // strList.add(sb.toString()); // break; // } // flag = trSEO靠我ue; // } else { // if (flag) { // strList.add(sb.toString()); // sb.SEO靠我delete(0, sb.length()); // } // flag = false; // } //} //strSEO靠我List.forEach(System.out::println);

注意:toString方法是转成符合数据库导入格式的数据,toRedis是转成符号redis导入的格式(我不太确定这种方式的效率,并SEO靠我且我最终没有采用这种方法)。

说明:

1.这里的处理逻辑很简单,就是将文件分行读入内存,然后对每一行切分成4块,然后调用编写的ip2Long方法进行处理即可。

2.如果可以使用正则表达式,尽量用正则表达式,SEO靠我特别是这种数据处理,速度差距非常之大!

3.这个ip2Long方法,是我从jdk的ObjectInpustream里面拿来的,随便修改了一下,原来的代码使用的是byte,但是这里如果传入一个尝试把一个大SEO靠我于127的数转成int会抛出异常,所以使用int数组代替了byte数组,并且由于我这里只有32位,所以我就删除了后32位的处理代码。

执行结果:

这个notepad++打开大文件感觉还行,40多m也能流畅SEO靠我使用。我这里使用excel打开就比较慢了,而且中文乱码了,就不放截图了。如果使用excel打开的话和普通的excel文件显示没有什么区别。我这里转成csv的原因是:

a).csv文件本身就是文本格式,使SEO靠我用程序直接输出即可。

b).我使用的sqlyog社区版无法导入excel数据,只能导入csv格式的数据。

csv格式数据

redis格式的数据,直接就是一条命令,但是它总共是52万+的数据,想必一条一条的执SEO靠我行,时间上也会接受不了,但是这个给我了启发,我后来在redis中使用了这种格式来存储值(json数据)。

redis格式数据(没有使用)

数据入库

因为我使用的是sqlyog,数据导入有一点麻烦,如果使用其SEO靠我它的数据库客户端应该会简单一些。

建库建表

这个建表语句参考了别人的博客,做了一些修改(添加了原始的ip起始地址和结束地址、修改了表的字符编码)

CREATE TABLE `ip_data` ( SEO靠我 `ipstart` INT(10) UNSIGNED NOT NULL, # 开始ip地址 `ipend` INT(10) UNSIGNED NOT NULL, # 结束ip地址SEO靠我 `area` VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, # 区域 SEO靠我`location` VARCHAR(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, # 位置 `ipsSEO靠我tartstr` VARCHAR(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, # 开始ip地址的点分表示方式 SEO靠我 `ipendstr` VARCHAR(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL, # 结束ip地址的点分表示方SEO靠我式 PRIMARY KEY (`ipstart`), INDEX `ip` (`ipstart`, `ipend`) USING BTREE ) SEO靠我 ENGINE=INNODB DEFAULT CHARACTER SET=utf8mb4 COLLATE=utf8mb4_general_ci;

导入数据

我直接使用sqlyog的SEO靠我导入csv,但是没有成功。它的图形界面导入功能感觉就很鸡肋,我就没成功过,最后没办法,从网上查找到了如下命令,然后导入了csv文件,速度还行!

LOAD DATA LOCAL INFILE "C:/UsSEO靠我ers/Alfred/Desktop/data/test/qqwry.csv" INTO TABLE `poem_land`.`qqwry_ip` FIELDS TERMINATED SEO靠我BY , LINES TERMINATED BY \r\n;

数据查询

数据行数量 简单查看几行数据 查询数据 好了,还算不错!

数据存入redis

关系型数据库的查询效果可能不够理想,这里使用redis这个nosSEO靠我ql来提高查询性能,首先要做的还是数据导入。我发现这个数据导入真的是麻烦哎,昨天这个东西搞了我好久,当然也因为我对redis并不熟悉。

上面说了,我没有采用那种一条一条执行命令的方式,而是使用了一种更加SEO靠我快速的方式——redis的管道技术。网上看了好多资料才搞成,第一次听说这个东西,效果确实很好!这里我们要做的是使用redis的管道技术将mysql数据导入到redis。

导入数据命令

sudo mysqlSEO靠我 -uroot -ppassword poem_land --skip-column-names --raw < data.sql | ./redis-4.0.11/src/redis-cli -h SEO靠我host -p port -a password --pipe

参数:

password:mysql数据库密码、redis密码

host:redis所在主机

port:redis所用端口

data.sql:一个SEO靠我sql文件,执行它会将数据库数据转成适合于redis导入的形式。

data.sql 文件

注意:redis_member 就是存入redis的值,这里我采用数据库的CONCAT函数把所有列拼成了一个jsoSEO靠我n字符串的形式,这样的话查询就可以获取到全部数据了,我是第一次这样用,不知道其它更好的方式(不过,导入时间却耗费了好几分钟,估计是拼接字符串影响了性能)。

SELECT CONCAT(*4\r\n,$,SEO靠我LENGTH(redis_cmd),\r\n,redis_cmd,\r\n,$,LENGTH(redis_key),\r\n,redis_key,\r\n,$,LENGTH(redis_score),SEO靠我\r\n,redis_score,\r\n,$,LENGTH(redis_member),\r\n,redis_member,\r ) FROM (SELECT ZADD AS redSEO靠我is_cmd,qqwry AS redis_key,ipend AS redis_score,CONCAT({"ipstart":, ipstart, ,"ipend":, ipend,,"area"SEO靠我:", `area`, ","location":", location, "}) AS redis_member FROM `poem_land`.`qqwry_ip` ) AS NSEO靠我AME

导入结果 查询数据

Springboot结合使用

我最终的目的,还是要提供一个查询的接口来使用。现在就将它作为服务提供了,让我们开始吧!

控制器代码

这里我使用的是mybatis_plus和它的生成器,所SEO靠我以代码是自动生成的,基本上只需要看这个Controller的代码就行了。

package org.dragon.ip_seek.controller;import java.util.Map; SEO靠我 import java.util.Objects; import java.util.Set;import javax.servlet.http.HttpServletRequSEO靠我est;import org.dragon.ip_seek.entity.QqwryIp; import org.dragon.ip_seek.service.IQqwryIpServSEO靠我ice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sprSEO靠我ingframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.SEO靠我RedisTemplate; import org.springframework.http.MediaType; import org.springframeworkSEO靠我.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMappiSEO靠我ng; import org.springframework.web.bind.annotation.RestController;import com.baomidou.mybatiSEO靠我splus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkitSEO靠我.Wrappers; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasSEO靠我terxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMaSEO靠我pper;/*** <p>* 前端控制器* </p>** @author Alfred* @since 2020-12-08*/ @RestController @ReSEO靠我questMapping("/seeker/") public class QqwryIpController {private static final Logger logger SEO靠我= LoggerFactory.getLogger(QqwryIpController.class);private static final String ipRegex = "\\."; // 匹SEO靠我配ip的正则表达式@Autowiredprivate IQqwryIpService iqqwryIpService; // mysql 服务调用@Autowiredprivate RedisTempSEO靠我late<String, String> redisTemplate; // redis 服务调用@GetMapping(value = "/poem1", produces = MediaType.SEO靠我APPLICATION_JSON_VALUE)public String test01(HttpServletRequest request) {// 本地局域网测试,ip地址是内网地址,无法使用,这SEO靠我里我先传递一个模拟的ip地址。String host = request.getRemoteHost();logger.info("当前用户的ip地址为:{}", host);Map<String, SEO靠我String> ipInfo = iqqwryIpService.getIpInfo("60.174.231.10");ipInfo.forEach((k, v) -> {logger.info("KSEO靠我:{} V:{}", k, v);});return "{\"poem\": \"一日不见兮,思之如狂。\"}";}@GetMapping(value = "/poem_mysql", produceSEO靠我s = MediaType.APPLICATION_JSON_VALUE)public Map<String, Object> test02(HttpServletRequest request) {SEO靠我String host = request.getRemoteHost(); // 本地局域网测试,ip地址是内网地址,无法使用,这里我先传递一个模拟的ip地址。// 如果部署到云服务器上,去掉此行即SEO靠我可。host = "60.174.231.10";LambdaQueryWrapper<QqwryIp> wrapper = Wrappers.lambdaQuery();// 忘记了,eclipseSEO靠我自己的编译器不支持这个 SFunction接口wrapper.select(QqwryIp::getArea, QqwryIp::getLocation).apply("INET_ATON({0}) SEO靠我between ipstart and ipend", host);Map<String, Object> info = iqqwryIpService.getMap(wrapper);Map<StrSEO靠我ing, Object> ipInfoMap = new java.util.LinkedHashMap<>(); // 我想要指定map序列化的键值对顺序为:ip area locationipInSEO靠我foMap.put("ip", host);if (Objects.nonNull(info)) {ipInfoMap.putAll(info);}logger.info("通过mysql查询 ip:SEO靠我 {}", ipInfoMap.get("ip"));return ipInfoMap; // "{\"poem\": \"一日不见兮,思之如狂。\"}";}/*** 采用 Redis 缓存的方式进行SEO靠我服务调用* @param <T>* */@GetMapping(value = "/poem_redis", produces = MediaType.APPLICATION_JSON_VALUE)pSEO靠我ublic Map<String, Object> test03(HttpServletRequest request) {String host = request.getRemoteHost();SEO靠我host = "116.62.188.176"; // 本来想测试一个错误数据的:256.256.266.255,结果long都溢出了,直接变成了0// 从redis中查询数据Set<String> SEO靠我resultSet = redisTemplate.opsForZSet().rangeByScore("qqwry", ip2Long(host), Double.MAX_VALUE, 0, 1);SEO靠我logger.info("通过reids查询 ip: {}", host);return transfer(resultSet, host);}/*** 对redis查询数据做一个转换,使之格式更加友SEO靠我好* */@SuppressWarnings("unchecked")private Map<String, Object> transfer(Set<String> resultSet, StrinSEO靠我g host) {Map<String, Object> ipInfoMap = new java.util.LinkedHashMap<>(); // 我想要指定map序列化的键值对顺序为:ip aSEO靠我rea locationipInfoMap.put("ip", host);if (resultSet.isEmpty()) {ipInfoMap.put("area", "NAN");ipInfoMSEO靠我ap.put("location", "NAN");return ipInfoMap;}String result = resultSet.toArray(new String[0])[0];Map<SEO靠我String, Object> info = null;ObjectMapper mapper = new ObjectMapper();try {info = mapper.readValue(reSEO靠我sult, Map.class); // 这里泛型会被擦除,直接赋值会报编译器警告,但是我也不知道Class<T>这种参数该如何传递了,就先抑制一下编译器警告吧if (Objects.nonNull(SEO靠我info)) {ipInfoMap.putAll(info);}} catch (JsonMappingException e) {e.printStackTrace();} catch (JsonPSEO靠我rocessingException e) {e.printStackTrace();}return ipInfoMap;}private long ip2Long(String ip) {StrinSEO靠我g[] strs = ip.split(ipRegex);int[] bs = new int[4];for (int i = 0; i < 4; i++) {bs[i] = Integer.parsSEO靠我eInt(strs[i]); // Byte.parseByte(strs[i]); 这个方法转成的字节范围是 -128-127,真是太坑了!}return ((bs[3] & 0xFFL) ) + SEO靠我// 这个转换方法是从jdk源码里面偷来的,挺好用的!((bs[2] & 0xFFL) << 8) +((bs[1] & 0xFFL) << 16) +((bs[0] & 0xFFL) << 24);SEO靠我} }

说明:

test01是传统的mybatis的写法,后来发现mybatis_plus可以使用更加简单的方法,就换成了test02,但是保留了test01。test03是从redis中SEO靠我进行数据查询。

效果演示

启动项目 test01——mysql

这里查询的结果,我是使用在日志上了,本来是打算在后台使用的,但是暂时也没啥想法,就算了。

test02——mysql test03——redis

注意SEO靠我:因为我本地测试,它获取的是本地的ip地址(127.0.0.1),所以我就在后台硬编码了一个公网ip地址来查询。

PS

我最近看到了一个基于java的开源软件——JMeter。它可以用来做压力测试,但是我SEO靠我并不会。但是,这并不妨碍我来玩一玩!

下面的内容仅供参考,我只是玩一玩!

步骤:启动JMeter,然后创建一个线程组(1000个线程,50s,循环两次),添加一个Http请求,添加一个查看结果树,添加一个SEO靠我聚合报告,启动。

接口:poem_mysql 接口:poem_redis

说明这里是两千个请求,从聚合报告里面看似乎redis确实性能是远远超过了mysql(我听别人说也是这样的),但是由于这个测试不严谨,SEO靠我我也不会JMeter,所以就不作为一个有效的参考了。

参数资源:

纯真数据库查询

查询网ip查询

通过管道传输快速将MySQL的数据导入Redis

使用redis有序集合搭建自有ip定位解析库

将mysql表数据SEO靠我批量导入redis zset结构中

IPLook解析纯真数据库,我没有使用这个软件,因为我是手动解析数据

mysql快速导入大量数据问题

一个简单的方式,但是有效率问题

ip location介绍

redis的SEO靠我简单配置

jackson json map object 之间互相转换
“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2