使用python来抓取新浪的IP数据
浏览:7383次 出处信息
数据分析,特别是网站分析中需要对访问者的IP进行分析,分析IP中主要是区分来访者的省份+城市+行政区数据,考虑到目前纯真IP数据库并没有把这些数据做很好的区分,于是寻找了另外一个可行的方案(当然不是花钱买哈)。解决方案就是抓取新浪的IP数据。
新浪的IP数据接口为:
http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=123.124.2.85
返回的数据为:
{"ret":1,"start":"123.123.221.0","end":"123.124.158.29","country":"\u4e2d\u56fd","province":"\u5317\u4eac","city":"\u5317\u4eac","district":"","isp":"\u8054\u901a","type":"","desc":""}
其返回的内容中已经包含了省份+城市+行政区信息了,这就是我们真实想要的。
下面就来说说如何来抓取这部分IP数据,要抓取这部分数据的主要工作就是枚举,即将接口中的IP不断的替换,要替换所有的IP地址肯定不太可能,所以我们缩小下范围,只穷举所有中国的IP段。考虑到新浪的IP接口返回的是IP段,所以要穷举的部分又少了一部分。再考虑啊到IP段的最后一位及256个IP基本上都是在一个地区,所以我们要穷举的数据有少了很多。对于穷举最重要的是把IP地址换成INT型。
具体国内有多少IP地址段,可以到APNIC官方网站去查找或下面的文档
http://ftp.apnic.net/apnic/dbase/data/country-ipv4.lst
下面就来看看穷举程序如何写:
import re
def ipv3_to_int(s): l = [int(i) for i in s.split('.')] return (l[0] << 16) | (l[1] << 8) | l[2]
def int_to_ipv3(s): ip1 = s >> 16 & 0xFF ip2 = s >> 8 & 0xFF ip3 = s & 0xFF return "%d.%d.%d" % (ip1, ip2, ip3)
i = open('ChinaIPAddress.csv', 'r') list = i.readlines() for iplist in list: pattern = re.compile('(\d{1,3}\.\d{1,3}\.\d{1,3})\.\d{1,3}') ips = pattern.findall(iplist) x = ips[0] y = ips[1] for ip in range (ipv3_to_int(x),ipv3_to_int(y)): ipadress=str(ip) #ip_address = int_to_ipv3(ip) o = open('ChinaIPAddress.txt','a') o.writelines(ipadress) o.writelines('\n') o.close() i.close()
当上面的不走完成后就可以对新浪IP接口进行抓取了,抓取代码如下:
#!/usr/bin/python # -*- coding: utf-8 -*- import urllib,urllib2, simplejson, sqlite3, time
def ipv3_to_int(s): l = [int(i) for i in s.split('.')] return (l[0] << 16) | (l[1] << 8) | l[2]
def int_to_ipv4(s): ip1 = s >> 16 & 0xFF ip2 = s >> 8 & 0xFF ip3 = s & 0xFF return "%d.%d.%d.0" % (ip1, ip2, ip3)
def fetch(ipv4, **kwargs): kwargs.update({ 'ip': ipv4, 'format': 'json', }) DATA_BASE = "http://int.dpool.sina.com.cn/iplookup/iplookup.php" url = DATA_BASE + '?' + urllib.urlencode(kwargs) print url fails = 0 try: result = simplejson.load(urllib2.urlopen(url,timeout=20)) except (urllib2.URLError,IOError): fails += 1 if fails < 10: result = fetch(ipv4) else: sleep_download_time = 60*10 time.sleep(sleep_download_time) result = fetch(ipv4) return result
def dbcreate(): c = conn.cursor() c.execute('''create table ipdata( ip integer primary key, ret integer, start text, end text, country text, province text, city text, district text, isp text, type text, desc text )''') conn.commit() c.close()
def dbinsert(ip,address): c = conn.cursor() c.execute('insert into ipdata values(?,?,?,?,?,?,?,?,?,?,?)',(ip,address['ret'],address['start'],address['end'],address['country'],address['province'],address['city'],address['district'],address['isp'],address['type'],address['desc'])) conn.commit() c.close()
conn = sqlite3.connect('ipaddress.sqlite3.db') dbcreate()
i = open('ChinaIPAddress.txt','r') list = [s.strip() for s in i.readlines()] end = 0 for ip in list: ip = int(ip) if ip > end : ipaddress = int_to_ipv4(ip) info = fetch(ipaddress) if info['ret'] == -1: pass else: dbinsert(ip,info) end = ipv3_to_int(info['end']) print ip,end else : pass i.close()
到此就能把新浪所有的国内IP数据给抓取出来,然后在数据分析的工程中大派用场。~
建议继续学习:
- 获取指定(访客)IP的所有信息,地址、邮政编码、国家、经纬度等的API (阅读:5375)
- 命令行获取主机外网IP,相当于ip138的功能 (阅读:5014)
- 计算机网络协议包头赏析-IP (阅读:4848)
- 当网站使用CDN后获取客户端真实IP的方法 (阅读:4623)
- nginx在fastcgi模块中转发真实的后端IP (阅读:4047)
- 获取客户端真实IP方法 (阅读:3838)
- nginx.conf控制指定的代理ip和ip访问的设置手记 (阅读:3526)
- 重谈IP欺骗技术 (阅读:3431)
- ip地址中的网络号,主机号 (阅读:3455)
- 验证IP属于国内还是国外的PHP类,可限制国内IP用户 (阅读:3173)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
扫一扫订阅我的微信号:IT技术博客大学习
<< 前一篇:Firefox的about 页面
后一篇:你从未听说过的一种编程方式 >>
文章信息
- 作者:标点符 来源: 标点符
- 标签: IP
- 发布时间:2012-01-27 18:41:19
建议继续学习
近3天十大热文
- [2202] 代理的加密部分
- [981] 创业笔记 | 从0到1开公司是什么体验
- [304] vimgtd-在vim(gvim)中实现GT
- [239] 查找第K小的元素
- [61] Oracle MTS模式下 进程地址与会话信
- [59] Go Reflect 性能
- [59] 【社会化设计】自我(self)部分――欢迎区
- [57] 图书馆的世界纪录
- [56] android 开发入门
- [55] 如何拿下简短的域名