標籤:python
一、擷取最新版IP地址資料庫qqwry.dat
純真IP地址資料庫:http://update.cz88.net/soft/setup.zip
在windows機器上下載解壓,點擊setup.exe安裝,在安裝目錄下的qqwry.dat即是最新版ip資料庫。
也可從51CTO下載(不是最新版,可用於測試):http://down.51cto.com/data/1888530
二、IPLocator.py
網上找到別人用Python寫的純真IP資料庫的查詢程式,原文地址:http://blog.chinaunix.net/uid-20758462-id-1876988.html,本文對代碼做了一些修改,解決中文亂碼問題。
建立IPLocator.py檔案(見本文附件),內容如下:
#! /usr/bin/env python# -*- coding: utf-8 -*-""" IPLocator: locate IP in the QQWry.dat. Usage: python IPLocator.py <ip>"""import socket,string,struct,sysclass IPLocator : def __init__( self, ipdbFile ): self.ipdb = open( ipdbFile, "rb" ) str = self.ipdb.read( 8 ) (self.firstIndex,self.lastIndex) = struct.unpack(‘II‘,str) self.indexCount = (self.lastIndex - self.firstIndex)/7+1 print self.getVersion()," 紀錄總數: %d 條 "%(self.indexCount) def getVersion(self): s = self.getIpAddr(0xffffff00L) return s def getAreaAddr(self,offset=0): if offset : self.ipdb.seek( offset ) str = self.ipdb.read( 1 ) (byte,) = struct.unpack(‘B‘,str) if byte == 0x01 or byte == 0x02: p = self.getLong3() if p: return self.getString( p ) else: return "" else: self.ipdb.seek(-1,1) return self.getString( offset ) def getAddr(self,offset,ip=0): self.ipdb.seek( offset + 4) countryAddr = "" areaAddr = "" str = self.ipdb.read( 1 ) (byte,) = struct.unpack(‘B‘,str) if byte == 0x01: countryOffset = self.getLong3() self.ipdb.seek( countryOffset ) str = self.ipdb.read( 1 ) (b,) = struct.unpack(‘B‘,str) if b == 0x02: countryAddr = self.getString( self.getLong3() ) self.ipdb.seek( countryOffset + 4 ) else: countryAddr = self.getString( countryOffset ) areaAddr = self.getAreaAddr() elif byte == 0x02: countryAddr = self.getString( self.getLong3() ) areaAddr = self.getAreaAddr( offset + 8 ) else: countryAddr = self.getString( offset + 4 ) areaAddr = self.getAreaAddr() return countryAddr + " " + areaAddr def dump(self, first ,last ): if last > self.indexCount : last = self.indexCount for index in range(first,last): offset = self.firstIndex + index * 7 self.ipdb.seek( offset ) buf = self.ipdb.read( 7 ) (ip,of1,of2) = struct.unpack("IHB",buf) address = self.getAddr( of1 + (of2 << 16) ) #把GBK轉為utf-8 address = unicode(address,‘gbk‘).encode("utf-8") print "%d\t%s\t%s" %(index, self.ip2str(ip), address ) def setIpRange(self,index): offset = self.firstIndex + index * 7 self.ipdb.seek( offset ) buf = self.ipdb.read( 7 ) (self.curStartIp,of1,of2) = struct.unpack("IHB",buf) self.curEndIpOffset = of1 + (of2 << 16) self.ipdb.seek( self.curEndIpOffset ) buf = self.ipdb.read( 4 ) (self.curEndIp,) = struct.unpack("I",buf) def getIpAddr(self,ip): L = 0 R = self.indexCount - 1 while L < R-1: M = (L + R) / 2 self.setIpRange(M) if ip == self.curStartIp: L = M break if ip > self.curStartIp: L = M else: R = M self.setIpRange( L ) #version information,255.255.255.X,urgy but useful if ip&0xffffff00L == 0xffffff00L: self.setIpRange( R ) if self.curStartIp <= ip <= self.curEndIp: address = self.getAddr( self.curEndIpOffset ) #把GBK轉為utf-8 address = unicode(address,‘gbk‘).encode("utf-8") else: address = "未找到該IP的地址" return address def getIpRange(self,ip): self.getIpAddr(ip) range = self.ip2str(self.curStartIp) + ‘ - ‘ + self.ip2str(self.curEndIp) return range def getString(self,offset = 0): if offset : self.ipdb.seek( offset ) str = "" ch = self.ipdb.read( 1 ) (byte,) = struct.unpack(‘B‘,ch) while byte != 0: str = str + ch ch = self.ipdb.read( 1 ) (byte,) = struct.unpack(‘B‘,ch) return str def ip2str(self,ip): return str(ip>>24)+‘.‘+str((ip>>16)&0xffL)+‘.‘ +str((ip>>8)&0xffL)+‘.‘+str(ip&0xffL) def str2ip(self,s): (ip,) = struct.unpack(‘I‘,socket.inet_aton(s)) return ((ip>>24)&0xffL)|((ip&0xffL)<<24) |((ip>>8)&0xff00L)|((ip&0xff00L)<<8) def getLong3(self,offset = 0): if offset : self.ipdb.seek( offset ) str = self.ipdb.read(3) (a,b) = struct.unpack(‘HB‘,str) return (b << 16) + a#Demodef main(): IPL = IPLocator( "qqwry.dat" ) ip = "" if len(sys.argv) != 2: print ‘Usage: python IPLocator.py <IP>‘ return else: ip = sys.argv[1] address = IPL.getIpAddr( IPL.str2ip(ip) ) range = IPL.getIpRange( IPL.str2ip(ip) ) print "此IP %s 屬於 %s\n所在網段: %s" % (ip,address, range)if __name__ == "__main__" : main()
把qqwry.dat放到和IPLocator.py同一目錄,使用方法如下(請參考IPLocator.py中的Demo):
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/56/B6/wKiom1SKxheTBaiIAAOTHHV72tE754.jpg" title="IP.png" alt="wKiom1SKxheTBaiIAAOTHHV72tE754.jpg" />
本文出自 “啟程的Linux部落格” 部落格,請務必保留此出處http://qicheng0211.blog.51cto.com/3958621/1589442
Python讀取純真IP資料庫