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 + " ")
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'))