python读取QQWry.Dat的代码


这里采用Python读取QQWry.Dat的IP数据库,并返回所需的省市名称。

  1. #!/usr/bin/python
  2. # coding=cp936
  3.  
  4. from struct import*
  5. import string, sys
  6.  
  7. def ip2string(ip):
  8.     a = (ip & 0xff000000) >>24
  9.     b = (ip & 0x00ff0000) >>16
  10.     c = (ip & 0x0000ff00) >>8
  11.     d = ip & 0x000000ff
  12.     return '%d.%d.%d.%d' % (a, b, c, d)
  13.  
  14. def string2ip(mystr):
  15.     ss = string.split(mystr, '.');
  16.     ip = 0L
  17.     for s in ss:
  18.         ip = (ip << 8) + string.atoi(s)
  19.     return ip;
  20.  
  21. class IpLocater:
  22.     def __init__(self, ipdb_file):
  23.         self.ipdb = open(ipdb_file, 'rb')
  24.         # get index address
  25.         header = self.ipdb.read(8)
  26.         (self.first_index, self.last_index) = unpack('II', header)
  27.         self.index_count = (self.last_index - self.first_index) / 7 + 1
  28.  
  29.     def getString(self, offset = 0):
  30.         if offset :
  31.             self.ipdb.seek(offset)
  32.         mystr = ''
  33.         if self.ipdb.tell() == 0:
  34.            return '未知地区'
  35.         ch = self.ipdb.read(1)
  36.         (byte,) = unpack('B', ch)
  37.         while byte != 0:
  38.             mystr = mystr + ch
  39.             ch = self.ipdb.read(1)
  40.             (byte,) = unpack('B',ch)
  41.         return mystr
  42.  
  43.     def getLong3(self, offset = 0):
  44.         if offset :
  45.             self.ipdb.seek(offset)
  46.         mystr = self.ipdb.read(3)
  47.         (a,b) = unpack('HB', mystr)
  48.         return (b << 16) + a
  49.  
  50.     def getAreaAddr(self, offset=0):
  51.         if offset :
  52.             self.ipdb.seek(offset)
  53.         mystr = self.ipdb.read(1)
  54.         (byte,) = unpack('B', mystr)
  55.         if byte == 0x01 or byte == 0x02:
  56.            
  57.             p = self.getLong3()
  58.             if p:
  59.                 return self.getString(p)
  60.             else:
  61.                 return ''
  62.         else:
  63.            
  64.             self.ipdb.seek(self.ipdb.tell() - 1)
  65.             return self.getString()
  66.  
  67.     def getAddr(self, offset, ip = 0):
  68.         self.ipdb.seek(offset + 4)
  69.  
  70.         countryAddr = ''
  71.         areaAddr = ''
  72.         mystr = self.ipdb.read(1)
  73.         (byte,) = unpack('B', mystr)
  74.         if byte == 0x01:
  75.            
  76.             countryOffset = self.getLong3()
  77.             self.ipdb.seek(countryOffset)
  78.             mystr = self.ipdb.read(1)
  79.             (b,) = unpack('B', mystr)
  80.             if b == 0x02:
  81.                
  82.                 countryAddr = self.getString(self.getLong3())
  83.                 self.ipdb.seek( countryOffset + 4 )
  84.             else:
  85.                 countryAddr = self.getString(countryOffset)
  86.             areaAddr = self.getAreaAddr()
  87.         elif byte == 0x02:
  88.            
  89.             countryAddr = self.getString(self.getLong3())
  90.             areaAddr = self.getAreaAddr(offset + 8)
  91.         else:
  92.             countryAddr = self.getString(offset + 4)
  93.             areaAddr = self.getAreaAddr()
  94.         #print countryAddr
  95.         #print areaAddr
  96.         return countryAddr + '/' + areaAddr
  97.  
  98.     def output(self, first, last):
  99.         if last > self.index_count :
  100.             last = self.index_count
  101.         for index in range(first, last):
  102.             offset = self.first_index + index * 7
  103.             self.ipdb.seek(offset)
  104.             buf = self.ipdb.read(7)
  105.             (ip,of1,of2) = unpack('IHB', buf)
  106.             print '%s - %s' % (ip2string(ip), self.getAddr( of1 + (of2 <<
  107. 16)))
  108.  
  109.     def find(self, ip, left, right):
  110.         if right-left == 1:
  111.             return left
  112.         else:
  113.             middle = (left + right) / 2
  114.             offset = self.first_index + middle * 7
  115.             self.ipdb.seek(offset)
  116.             buf = self.ipdb.read(4)
  117.             (new_ip,) = unpack('I', buf)
  118.             if ip <= new_ip :
  119.                 return self.find(ip, left, middle)
  120.             else:
  121.                 return self.find(ip, middle, right)
  122.  
  123.     def getIpAddr(self, ip):
  124.         index = self.find(ip, 0, self.index_count - 1)
  125.         ioffset = self.first_index + index * 7
  126.         aoffset = self.getLong3(ioffset + 4)
  127.         address = self.getAddr(aoffset)
  128.         return address
  129.  
  130. def main(argv=None):
  131.     if len(sys.argv) != 2:
  132.        print 'usage: locate <ip>'
  133.        sys.exit(-1)
  134.     ip_locater = IpLocater(r'D:\robots\ip\QQWry.Dat')
  135.     ip_locater.output(1, 250000)
  136.     print '共有%d条记录' % ip_locater.index_count
  137.     ip = sys.argv[1]
  138.     address = ip_locater.getIpAddr(string2ip(ip))
  139.     print 'the ip %s come from %s' % (ip, address)
  140.  
  141. if __name__ == '__main__' :
  142.     main()

感谢您的关注。您现在可以 留言(0)留下通告地址



Leave a Reply

Note: Any comments are permitted only because the site owner is letting you post, and any comments will be removed for any reason at the absolute discretion of the site owner.

*
To prove you're a person (not a spam script), type the security word shown in the picture.
Anti-Spam Image