python3下urllib.request庫高級應用之ProxyHandler處理器_代理設置
使用代理IP,這是爬蟲/反爬蟲的第二大招,通常也是最好用的。
很多網站會檢測某一段時間某個IP的訪問次數(通過流量統計,系統日志等),如果訪問次數多的不像正常人,它會禁止這個IP的訪問。
所以我們可以設置一些代理服務器,每隔一段時間換一個代理,就算IP被禁止,依然可以換個IP繼續爬取。
在urllib.request庫中,通過ProxyHandler來設置使用代理服務器,下面通過例子來說明如何使用自定義opener來使用代理:
免費短期代理網站:西刺免費代理IP(http://www.xicidaili.com/)
免費短期代理網站分高匿和透明
【高匿】:代表服務器追蹤不到你原來的IP;
【透明】:代表服務器可以追蹤到你的代理IP和原來的IP;
類型表示支持的類型:HTTP或者HTTPS
【存活的時間】:表示在這個期間可用
例子一:單個代理IP
import urllib.request
url ="http://www.baidu.com/"
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
}
# 構建了兩個代理Handler,一個有代理IP,一個沒有代理IP
httpproxy_handler = urllib.request.ProxyHandler({"http" : "61.135.217.7:80"})
nullproxy_handler = urllib.request.ProxyHandler({})
proxySwitch = True #定義一個代理開關
# 通過 urllib2.build_opener()方法使用這些代理Handler對象,創建自定義opener對象
# 根據代理開關是否打開,使用不同的代理模式
if proxySwitch:
opener = urllib.request.build_opener(httpproxy_handler)
else:
opener = urllib.request.build_opener(nullproxy_handler)
request = urllib.request.Request(url,headers=header)
# 1. 如果這么寫,只有使用opener.open()方法發送請求才使用自定義的代理,而urlopen()則不使用自定義代理。
response = opener.open(request)
# 2. 如果這么寫,就是將opener應用到全局,之后所有的,不管是opener.open()還是urlopen() 發送請求,都將使用自定義代理。
# urllib2.install_opener(opener)
# response = urlopen(request)
print(response.read().decode('utf-8'))
運行結果:
如果代理IP足夠多,就可以像隨機獲取User-Agent一樣,隨機選擇一個代理去訪問網站。
例子二:代理IP列表隨機抽取
import urllib.request
import random
url ="http://www.baidu.com/"
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
}
proxy_list = [
{"http" : "61.135.217.7:80"},
{"http" : "111.155.116.245:8123"},
{"http" : "122.114.31.177:808"},
]
# 隨機選擇一個代理
proxy = random.choice(proxy_list)
# 使用選擇的代理構建代理處理器對象
httpproxy_handler = urllib.request.ProxyHandler(proxy)
opener = urllib.request.build_opener(httpproxy_handler)
request = urllib.request.Request(url,headers=header)
response = opener.open(request)
print(response.read().decode('utf-8'))
運行結果:
備注:免費開放代理一般會有很多人都在使用,而且代理有壽命短,速度慢,匿名度不高,HTTP/HTTPS支持不穩定等缺點,所以,專業爬蟲工程師或爬蟲公司會使用高品質的私密代理,這些代理通常需要找專門的代理供應商購買,再通過用戶名/密碼授權使用。
例如:
快代理:https://www.kuaidaili.com
這些專門的代理供應商提供的代理服務有多種,例如:私密代理、獨享代理(購買形式多種:可以購買一天、包月、包年),獨享代理價格比貴,適合於公司有這方面的需要才選擇去購買獨享代理,對於個人而言一般都是,一般都是選擇獨享代理。
下面介紹用私密代理實現的一個例子:
import urllib.request
url ="http://www.baidu.com/"
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
}
# 構建一個私密代理Handler,需要加上私密代理賬戶的用戶名和密碼
authproxy_handler=urllib.request.ProxyHandler({"http" :"username:password@61.135.217.7:80"})
opener = urllib.request.build_opener(authproxy_handler)
request = urllib.request.Request(url,headers=header)
response = opener.open(request)
print(response.read().decode('utf-8'))
備注:正常情況下,為了不暴露自己的代理賬戶和密碼,代理的賬戶和密碼,一般會提取出來,封裝到其他模塊,需要的時候再調用,或者使用os.environ.get()來讀取和修改環境變量。
例子:自定義的python的環境變量類:
import os
class MyEnv:
def __init__(self):
self.envFile = "d:\\myenv.txt"
self.envs = {}
def SetEnvFile(self, filename) :
self.envFile = filename
def Save(self) :
outf = open(self.envFile, "w")
if not outf:
print ("env file cannot be opened for write!")
for k, v in self.envs.items() :
outf.write(k + "=" + v + "\n")
outf.close()
def Load(self) :
inf = open(self.envFile, "r")
if not inf:
print ("env file cannot be opened for open!")
for line in inf.readlines() :
k, v = line.split("=")
self.envs[k] = v
inf.close()
def ClearAll(self) :
self.envs.clear()
def AddEnv(self, k, v) :
self.envs[k] = v
def RemoveEnv(self, k) :
del self.envs[k]
def PrintAll(self) :
for k, v in self.envs.items():
print ( k + "=" + v )
if __name__ == "__main__" :
myEnv = MyEnv()
myEnv.SetEnvFile("c:\\myenv.txt")
myEnv.Load()
myEnv.AddEnv("MYDIR", "d:\\mydir")
myEnv.AddEnv("MYDIR2", "d:\\mydir2")
myEnv.AddEnv("MYDIR3", "d:\\mydir3")
myEnv.Save()
myEnv.PrintAll()
運行結果:
使用os.environ來讀取和修改環境變量:
import urllib.request
import os
username=os.environ.get("username")
password =os.environ.get("password")
print(username)
print(password)
url ="http://www.baidu.com/"
header={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
}
# 構建一個私密代理Handler,需要加上私密代理賬戶的用戶名和密碼
authproxy_handler=urllib.request.ProxyHandler({"http" :username+':'+"password@61.135.217.7:80"})
opener = urllib.request.build_opener(authproxy_handler)
request = urllib.request.Request(url,headers=header)
response = opener.open(request)
print(response.read().decode('utf-8'))