题记:2017第一弹~
简介
本站是先收集了中国所有的公有IP地址段,众所周知中国的IP地址是由APNIC(亚太网络信息中心)分配的,APNIC专门负责亚洲和太平洋地区的IP地址和AS号分配,受到 IANA(互联网地址分配机构) 的管理。所以本站先从http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest
下载到本地作为src.html
这里将所有的中国公网IP地址信息都进行提取过滤
具体生成器函数如下:
1 | def net_catch(): |
src.html里面包含了世界上所有的公网网段地址,形如:
1 | apnic|LK|ipv4|203.189.184.0|2048|20060515|allocated |
上述条目由如下字段构成:
分配机构 | 国家代码|ip版本| 网段 | 包含ip地址数量 | 分配时间 | 状态
我们只需要找到所有以apnic|CN|ipv4
开始的行,并以int(32-log(float(cnt))/log(2)
这个计算网段的掩码即可,并生成网段地址和掩码
在这个生成器之上我们就可以轻易生成中国所有的公网IP地址段,我们可以将其写入一个文件
1 | # |
利用淘宝IP地址库对网段信息进行查询
对淘宝IP库的简介
目前提供的服务包括:
- 根据用户提供的IP地址,快速查询出该IP地址所在的地理信息和地理相关的信息,包括国家、省、市和运营商。
- 用户可以根据自己所在的位置和使用的IP地址更新我们的服务内容。
优势: - 提供国家、省、市、县、运营商全方位信息,信息维度广,格式规范。
- 提供完善的统计分析报表,省准确度超过99.8%,市准确度超过96.8%,数据质量有保障
由于淘宝ip地址库支持rest api,所以我们很方便对我们想要的信息进行采集,先看下他的接口
- 请求接口(GET):
/service/getIpInfo.php?ip=[ip地址字串] - 响应信息:
(json格式的)国家 、省(自治区或直辖市)、市(县)、运营商等等 - 返回数据格式:这是一串json数据,格式化后便于我们对数据特点进行分析:
1
2
3
4{"code":0,"data":{"ip":"210.75.225.254","country":"\u4e2d\u56fd","area":"\u534e\u5317",
"region":"\u5317\u4eac\u5e02","city":"\u5317\u4eac\u5e02","county":"","isp":"\u7535\u4fe1",
"country_id":"86","area_id":"100000","region_id":"110000","city_id":"110000",
"county_id":"-1","isp_id":"100017"}}其中1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18{
"code": 0,
"data": {
"ip": "210.75.225.254",
"country": "中国",
"area": "华北",
"region": "北京市",
"city": "北京市",
"county": "",
"isp": "电信",
"country_id": "86",
"area_id": "100000",
"region_id": "110000",
"city_id": "110000",
"county_id": "-1",
"isp_id": "100017"
}
}code
的值的含义为,0:成功,1:失败。data
中包含了我们想要的信息,有ip地址(GET查询的IP地址,下面的信息都是针对此ip地址),国家,地区,省,市,isp信息,国家id,地区id,省id,市id,isp id信息
我们可以用之前得到的所有中国公网IP地址段,或者用他们的第一个主机位,借助这个地址库进行查询,并收集isp信息,我们可以以ISP name为名,并将查询到的isp信息追加写入到对应的文件中
我在抓取的过程中发现有的IP是没有ISP
的,即isp
为一个空值,我在逻辑的处理上将其写入到了一个error.txt
部分代码:
1 | def ip_resolve(ip,mask,retry_num=2): |
由于淘宝ip库限制了REST API查询的速率10QPS
,所以目前我只设置了延时timeout时间为0.09s
,此处应该还需要考虑代理,然而我并没有这么做
view设置
脚本运行后会在目录下生成很多acl文件,如下
1 | 263网络.acl 阿里云.acl 歌华网络.acl 可口可乐网络.acl 上海信息网络.acl 网宿科技.acl 有线通.acl |
一个文件代表一个isp信息,而智能DNS就是根据这些acl文件,也就是线路ip库来匹配,对于不同的Local DNS从而返回不同的解析记录,我们可以由此进行设置view视图,在主配置文件中include 这些acl文件即可,在此不在赘述,详情可见本站的第一篇bind view的使用
数据入库
并发方面由于臭名昭著的GIL,我就简单使用了进程池进行处理,生成四个子进程对数据进行操作,父进程则阻塞在p.join
等待子进程全部完成
由于python解释器
存在GIL
的限制,python
的多线程不适用于cpu
密集型的操作,但是这里数据采集是典型的IO bound
所以我用多线程尝试了下,效率还是可观的,但是一开始我采用的是concurrent.futures
的ThreadPoolExecutor
这个经过封装的线程池,但是莫名遇到很多问题,还是用了原生的线程。
数据的入库我用了一个生产者和消费者的模型,多线程采集数据之后压入Queue
,之后启动一个消费者线程去连接mysql
,将数据写入mysql
首先创建数据库和表:
1 | mysql> CREATE DATABASE tabaoip; |
使用python
去连接mysql
观察有没有成功
1 | import MySQLdb |
1 | zhxfei@HP-ENVY:~/learning/workspace1$ python mysql_insert.py |
准备好数据库就可以采集数据了
数据入库的代码:
1 | #!/usr/bin/python |
采集的记录实例:
1 | mysql> select * from c_ip_addr_info limit 10; |
感受下:
1 | 7621 rows in set (0.01 sec) |