在做采集器的過程中,經常會遇到IP限制的情況,這時候可以通過切換IP能繼續訪問。如果是多IP的服務器,那么可以通過切換出口Ip來實現。
首先是如何獲取服務器綁定的IP
1 import netifaces as ni 2 def getLocalEthIps(): 3 for dev in ni.interfaces(): 4 if dev.startswith('eth0'): 5 ip=ni.ifaddresses(dev)[2][0]['addr'] 6 if ip not in ipList: 7 ipList.append(ip) 8 print getLocalEthIps()
需要引入netifaces模塊,安裝方法easy_install netifaces
其次為socketban
1 # -*- coding=utf-8 -*- 2 import socket 3 import urllib2 4 import re 5 true_socket = socket.socket 6 7 ipbind='xx.xx.xxx.xx' 8 9 def bound_socket(*a, **k): 10 sock = true_socket(*a, **k) 11 sock.bind((ipbind, 0)) 12 return sock 13 14 socket.socket = bound_socket 15 16 response = urllib2.urlopen('http://www.ip.cn') 17 html = response.read() 18 ip=re.search(r'code.(.*?)..code',html) 19 print ip.group(1)
后面這個是通過訪問ip.cn來驗證實際外網IP, 正則原來是r'<code>(.*?)</code>'的,由於博客的代碼沖突,所以就改了下。
全部-實現的隨機綁定出口IP
1 #!/usr/bin/python 2 # -*- coding: utf-8 -*- 3 import socket 4 import random 5 import netifaces as ni 6 7 true_socket = socket.socket 8 ipList=[] 9 10 class getLocalIps(): 11 global ipList 12 def getLocalEthIps(self): 13 for dev in ni.interfaces(): 14 if dev.startswith('eth0'): 15 ip=ni.ifaddresses(dev)[2][0]['addr'] 16 if ip not in ipList: 17 ipList.append(ip) 18 19 class bindIp(): 20 ip='' 21 global true_socket,ipList 22 23 def bound_socket(self,*a, **k): 24 sock = true_socket(*a, **k) 25 sock.bind((self.ip, 0)) 26 return sock 27 28 def changeIp(self,ipaddress): 29 self.ip=ipaddress 30 if not self.ip=='': 31 socket.socket = self.bound_socket 32 else: 33 socket.socket = true_socket 34 35 def randomIp(self): 36 if len(ipList)==0: 37 getLocalIpsFunction=getLocalIps() 38 getLocalIpsFunction.getLocalEthIps() 39 if len(ipList)==0: 40 return 41 _ip=random.choice(ipList) 42 if not _ip==self.ip: 43 self.changeIp(_ip) 44 45 def getIp(self): 46 return self.ip 47 48 def getIpsCount(self): 49 return len(ipList)
調用示例
1 bindIpObj= bindIp() 2 #隨機切換IP 3 bindIpObj. randomIp() 4 #得到當前IP 5 print bindIpObj.getIp() 6 #得到本機IP數 7 print bindIpObj.getIpsCount() 8 #切換到指定IP 9 print bindIpObj. changeIp('xxx.xx.xx.xxx')