Nodejs淘宝IP地址库采集经验
Nodejs淘宝IP地址库采集经验
作者:阿宝 更新:2016-08-31 来源:彩色世界(https://blog.hz601.org/2016/08/31/taobao-ip-sniffer/index.html)
当初选择做这么一个项目,不是为了拷贝一份库自己做服务,也不是为了其他目的,只是单纯的熟悉关于http和mysql方面的知识。 下面言归正传。
1、淘宝IP地址库简介 此地址库可以根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家、省、市和运营商。 用户也可以主动提交信息来纠错。 主要优势表现为: (1)地域 覆盖度:94.54% 精确到市级 准确度:96.5% 精确到市级 (2)运营商 覆盖度:93.8% 准确度:暂无统计数据 (3)查询速度 10qps 注:阿里同机房内网,实测速度为4qps左右。 (4)接口 符合REST规范,方便扩展; 使用JSON作为数据格式,方便使用;
2、基础数据 下面介绍一下,需要使用到的一些基础数据项,以及来源。 首先,我们来分析一下淘宝IP地址库的返回数据, { “code” : 0, // 请求成功/失败 "data" : { “country” : “\u4e2d\u56fd”, // 国家 "country_id" : “CN”, // 国家代码 "area" : “\u534e\u5317”, // 地区 "area_id" : “100000”, // 地区代码 "region" : “\u5317\u4eac\u5e02”, // 省(自治区、直辖市、特别行政区) “region_id” : “110000”, // 省代码 "city" : “\u5317\u4eac\u5e02”, // 市(地区、自治州、盟及国家直辖市所属市辖区和县) “city_id” : “110000”, // 市代码 "county" : “”, // 县(市辖区、县级市、旗) “county_id” : “-1”, // 县代码 "isp" : “\u4e2d\u56fd\u79d1\u6280\u7f51”, // 运营商 "isp_id" : “1000114”, // 运营商代码 "ip" : “210.75.225.254” // ipv4/ipv6 } } 其中: 国家与国家代码,由联合国统计局统一制定。详见:http://zh.wikipedia.org/wiki/ISO_3166-1 地区、省、市、县以及相应的代码,由中华人民共和国国家统计局统一制定,详见:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html 运营商与运营商代码,由国际电联电信标准化部门统一制定,不过已经很久没有维护,不可用。到目前为止,本人也没有找到一份完整的编码表,希望知晓者告知。暂且就以淘宝IP地址库中编码为准。 国家IP地址段,由互联网IP地址分配中心统一管理,在此附上中文版的地址段信息,详见程默的博客,在此表示感谢:http://ipblock.chacuo.net/
3、数据库设计 (1)数据项及命名 国家 country 地区 region 省(自治区、直辖市、特别行政区) province 市(地区、自治州、盟及国家直辖市所属市辖区和县) city 县(市辖区、县级市、旗) county 镇(乡、城镇) town 村(村庄) village 运营商 isp IP ip
(2)IP表 国家代码 2个字节 CHAR(2) 县代码 6位整形 UINT(20) 村代码 12位整形 UINT(40) 运营商代码 7位整形 UINT(24) IP地址 4个字节 UINT(32)
(3)国家表 二位字母 2个字节 CHAR(2) 三位字母 3个字节 CHAR(3) 三位数字 3位整形 UINT(10) ISO英文用名 48个字节 CHAR(48) 中文用名 48个字节 CHAR(48)
(4)地区表 代码 1位整形 UINT(4) 名称 4个字节 CHAR(4)
(5)县(市辖区、县级市、旗)表 代码 6位整形 UINT(20) 名称 48个字节 CHAR(48)
(6)村(村庄)表 代码 12位整形 UINT(40) 名称 48个字节 CHAR(48)
(7)运营商表 代码 7位整形 UINT(24) 名称 48个字节 CHAR(48)
4、数据采集 IP运营商信息来源于各个运营商,IP所属地域信息来源于CNNIC,不过这些信息不太容易拿到完整的。 所以,此处就以淘宝IP地址库为来源。
5、实现方案 使用 nodejs + python 实现,nodejs主要实现网络交互集中的部分,python主要实现网页抓取。数据库使用常见的 mysql。 (1)国家代码抓取 使用 python 实现从 http://zh.wikipedia.org/wiki/ISO_3166-1 地址抓取代码信息,并保存文本country.txt。当然,也可以直接手动拷贝粘贴到文本中。 使用 nodejs 按行读取上一步抓取到的文本,做处理,使用 node-mysql 写入数据库。
(2)县代码抓取 使用 python 实现从 http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html 地址抓取代码信息,并保存文本cncounty.txt。当然,也可以直接手动拷贝粘贴到文本中。 使用 nodejs 按行读取上一步抓取到的文本,做处理,使用 node-mysql 写入数据库。
(3)国内IP段抓取 使用 python 实现从 http://ipblock.chacuo.net/ 地址抓取IP段信息,并保存文本cnip.txt。当然,也可以直接手动拷贝粘贴到文本中。
(4)IP地址信息查询 使用 nodejs 读取 cnip.txt 文本,每次解析10000个IP,使用 http 模块从淘宝IP地址库查询结果,并使用 node-mysql 写入数据库。 由于在 nodejs 中 http 处理和 mysql 处理都是异步操作,所以,增加一个缓冲区,保存http请求结果。笔者使用了经典的生产者消费者模型来处理这个问题。
6、结果 为了保证请求的稳定,使用阿里云服务器运行此系统。 实际运行时,每秒可以稳定的请求到5个IP信息,中国目前(截止2014年1月)拥有3.3亿IP,完成全部请求大约需要2.98天。 完成全部存储,数据库大小为22.3GB。
Nodejs淘宝IP地址库采集经验
作者: 阿宝
更新: 2016-08-31
来源: 彩色世界(原文链接)
当初选择做这么一个项目,不是为了拷贝一份库自己做服务,也不是为了其他目的,只是单纯的熟悉关于http和mysql方面的知识。
1. 淘宝IP地址库简介
淘宝IP地址库可以根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家、省、市和运营商。用户也可以主动提交信息来纠错。
主要优势表现为:
- 地域覆盖度:94.54%,精确到市级
- 地域准确度:96.5%,精确到市级
- 运营商覆盖度:93.8%
- 查询速度:10qps(阿里同机房内网,实测速度为4qps左右)
- 接口:符合REST规范,方便扩展;使用JSON作为数据格式,方便使用。
2. 基础数据
下面介绍一下,需要使用到的一些基础数据项,以及来源。
淘宝IP地址库的返回数据格式如下:
{
"code": 0, // 请求成功/失败
"data": {
"country": "\u4e2d\u56fd", // 国家
"country_id": "CN", // 国家代码
"area": "\u534e\u5317", // 地区
"area_id": "100000", // 地区代码
"region": "\u5317\u4eac\u5e02", // 省(自治区、直辖市、特别行政区)
"region_id": "110000", // 省代码
"city": "\u5317\u4eac\u5e02", // 市(地区、自治州、盟及国家直辖市所属市辖区和县)
"city_id": "110000", // 市代码
"county": "", // 县(市辖区、县级市、旗)
"county_id": "-1", // 县代码
"isp": "\u4e2d\u56fd\u79d1\u6280\u7f51", // 运营商
"isp_id": "1000114", // 运营商代码
"ip": "210.75.225.254" // IPv4/IPv6
}
}
3. 数据库设计
数据项及命名:
| 数据项 | 描述 |
|---|---|
| 国家 | country |
| 地区 | region |
| 省 | province |
| 市 | city |
| 县 | county |
| 运营商 | isp |
| IP地址 | ip |
IP表结构:
| 字段 | 类型 | 描述 |
|---|---|---|
| country_id | CHAR(2) | 国家代码 |
| area_id | INT(20) | 地区代码 |
| region_id | INT(20) | 省代码 |
| city_id | INT(20) | 市代码 |
| county_id | INT(20) | 县代码 |
| isp_id | INT(24) | 运营商代码 |
| ip | INT(32) | IP地址 |
4. 数据采集
IP运营商信息来源于各个运营商,IP所属地域信息来源于CNNIC,但这些信息不太容易拿到完整的。因此,此处就以淘宝IP地址库为来源。
5. 实现方案
使用 nodejs + python 实现,nodejs 主要实现网络交互集中的部分,python 主要实现网页抓取。数据库使用常见的 mysql。
具体步骤:
-
国家代码抓取:
- 使用
python抓取 ISO 3166-1 的国家代码,并保存到country.txt文件。 - 使用
nodejs按行读取文件,处理后写入数据库。
const fs = require('fs'); const mysql = require('mysql'); const connection = mysql.createConnection({ host: 'localhost', user: 'root', password: 'password', database: 'ip_database' }); connection.connect(); fs.readFile('country.txt', 'utf8', (err, data) => { if (err) throw err; data.split('\n').forEach(line => { const [code, name] = line.split('\t'); connection.query( 'INSERT INTO countries SET ?', { code, name }, (error, results) => { if (error) throw error; } ); }); }); - 使用
-
县代码抓取:
- 使用
python抓取县代码,并保存到cncounty.txt文件。 - 使用
nodejs按行读取文件,处理后写入数据库。
- 使用
-
国内IP段抓取:
- 使用
python抓取 IP 段信息,并保存到cnip.txt文件。
- 使用
-
IP地址信息查询:
- 使用
nodejs读取cnip.txt文本,每次解析10000个IP,使用http模块从淘宝IP地址库查询结果,并使用node-mysql写入数据库。 - 使用经典生产者消费者模型来处理异步请求和数据库写入。
- 使用
6. 结果
为了保证请求的稳定,使用阿里云服务器运行此系统。实际运行时,每秒可以稳定的请求到5个IP信息,中国目前(截止2014年1月)拥有3.3亿IP,完成全部请求大约需要2.98天。完成全部存储,数据库大小为22.3GB。
CNNIC的数据通过whois命令就能全部查询到, 不过不准, 基本省内的IP查询到的都是省会. 一般使用, 其实纯真的数据库精度也够了.
作者你好,小弟愚昧,请教个问题: 每秒可以稳定的请求到5个IP信息,中国目前(截止2014年1月)拥有3.3亿IP,完成全部请求大约需要2.98天,这是怎么计算的? 我的理解是一天可以收集的IP个数是: 56060*24=432000个; 那3.3亿的IP应该需要: 330000000/432000=763天左右。 希望得到作者的指点
根据提供的背景信息,我们可以基于 Node.js 来实现一个简单的 IP 地址信息采集程序。这里我将给出一个简化版本的示例,展示如何使用 Node.js 来进行 IP 地址查询并将结果保存到 MySQL 数据库中。
示例代码
首先,我们需要安装必要的 npm 包:
npm install mysql axios
接下来是 Node.js 的代码示例:
const mysql = require('mysql');
const axios = require('axios');
// 创建数据库连接
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'ip_data'
});
db.connect(err => {
if (err) throw err;
console.log('Connected to the database.');
});
// 读取 IP 段文件
const fs = require('fs');
const ipSegments = fs.readFileSync('cnip.txt', 'utf8').split('\n').slice(0, 100); // 仅读取前100个IP段示例
// 查询 IP 信息并存储到数据库
async function fetchAndStoreIPs() {
for (let segment of ipSegments) {
const [startIP, endIP] = segment.split('-');
// 向淘宝 IP 地址库发送请求
const response = await axios.get(`http://ip.taobao.com/service/getIpInfo.php?ip=${startIP}`);
// 将数据写入数据库
db.query('INSERT INTO ip_info SET ?', response.data.data, (error, results) => {
if (error) throw error;
console.log(`Inserted data for IP: ${startIP}`);
});
}
}
fetchAndStoreIPs();
解释
- MySQL 连接:创建一个数据库连接,用于向数据库写入数据。
- 读取 IP 段文件:使用
fs模块读取包含 IP 段的文件,并分割成数组。 - IP 信息查询:对于每个 IP 段,构造请求 URL 并使用
axios发送 HTTP GET 请求到淘宝的 IP 地址库。 - 数据入库:将查询得到的数据通过 SQL 插入到数据库中。
注意,上述代码仅作为示例,实际应用中可能需要考虑错误处理、并发控制等问题,以确保系统的稳定性。


