获取代理
在网上搜索代理网站(代理精灵、极光代理)。获取代理后,
在爬虫项目中新建一个爬虫脚本文件,用来抓取下来代理网站上获取的代理。然后存入redis数据库
- crawlippool.py
1 import requests 2 import redis 3 import json 4 url = "http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&qty=50&time=1&pro=&city=&port=1&format=json&ss=5&css=&ipport=1&et=1&pi=1&co=1&dt=1&specialTxt=3&specialJson=" 5 6 def update_ippool(): 7 res = requests.get(url=url) # 发起一个request请求 8 rds = redis.StrictRedis(host="www.fanjianbo.com",port=6379,db=9) # 链接redis数据库 9 dic = json.loads(res.text) # 反序列化 10 for item in dic["data"]: 11 rds.lpush("ippool",item) # 将数据存入redis,ippool 代理池 12 print("代理%s已经入库" % item) 13 if __name__ == '__main__': 14 update_ippool()
设置开启
在settings.py文件中开启中间件设置
- settings.py
1 DOWNLOADER_MIDDLEWARES = { 2 "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware":None, # 关闭系统代理中间件 3 'DushuPro.middlewares.ProxyDownloaderMiddleware': 543, # 开启自定义中间件 4 }
使用代理
在中间件中新定义一个类,来实现用代理爬取数据
- middlewares.py
1 from scrapy import signals 2 from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware 3 import redis 4 import random 5 import json 6 import requests 7 from crawlIppool import update_ippool 8 9 # 重写系统的代理类 10 class ProxyDownloaderMiddleware(object): 11 def __init__(self): 12 # 创建一个redis链接 13 self.rds = redis.StrictRedis(host="www.fanjianbo.com", port=6379, db=9) 14 self.ippool = self.get_ippool() # 获取代理到ippool代理池 15 16 # 定义一个函数用于从redis数据库中提取代理ip 17 def get_ippool(self): 18 len = self.rds.llen("ippool") #使用ip。获取此库的长度 19 proxies = self.rds.lrange("ippool",0,len) # 获取ip,从0到len之间提取 20 return proxies # 返回出去代理 21 22 # 重写中间的请求函数 23 def process_request(self, request, spider): 24 # 从代理池中随机的取出一个代理 25 ip = random.choice(self.ippool) 26 print("当前代理为:",ip) 27 try: 28 # 尝试一下ip代理有没有问题 29 ip_agnet = json.loads(ip.decode("utf-8").replace("'","\"")) 30 # 验证代理是否失效 31 # requests.get(url="http://www.baidu.com",proxies={"https":ip_agnet['IP']}) 32 33 # 给request下载器加代理 34 print("http://" + ip_agnet["IP"]) 35 request.meta["proxy"] = "http://" + ip_agnet["IP"] 36 37 except Exception as e: 38 print("代理--%s--已过期!"%ip_agnet) 39 # 从代理池中删除 40 self.ippool.remove(ip) 41 # redis服务器中也要删除 42 self.rds.lrem("ippool",value=ip) 43 # 当代理池中的代理小于10的时候更新一次代理池 44 if len(self.ippool) <= 10: 45 self.ippool += self.get_ippool() 46 # 当数据库中代理个数小于20的时候更新一次数据库 47 if self.rds.llen("ippool") <= 20: 48 update_ippool() # 获取代理的脚本函数