赞
踩
前言:
项目完成后,你要通过scrapy进行抓取;现在问题是,如果你还是用之前调好的延时爬取,你没必要用scrapy呀!那你这是什么效率,2-3秒抓一个url.疯了?
所以,这时候,我们需要给他装个ip_pool ; 没有它,你玩啥爬虫~爬蜗牛了就是;
正文:
抓ip的文章,我写在前面了
拿到这些ip,存哪是你自己的事;我个人建议是存redis,因为他最快;
然后,ip的代理业务写在哪里呢? scrapy的中间件
我个人是希望重新开一个类,专门给他定义成代理ip的类:
- import redis
- import random
- import time
-
- class ProxyMiddleware:
- def __init__(self):
- self.redis_client = redis.Redis()
- self.ip_cache = []
-
- def process_request(self, request, spider):
- # 从缓存中获取一个代理IP,并设置为请求的代理
- proxy_ip = self.get_proxy_ip()
- request.meta['proxy'] = proxy_ip
-
- def process_response(self, request, response, spider):
- # 处理响应,若状态码为403或429,则移除请求所使用的代理IP
- if response.status in [403, 429]:
- self.remove_proxy_ip(request.meta['proxy'])
- return response
-
- def process_exception(self, request, exception, spider):
- # 处理异常,将请求所使用的代理IP从缓存中移除
- self.remove_proxy_ip(request.meta.get('proxy'))
- return None
-
- def get_proxy_ip(self):
- # 若IP缓存数量少于10个,则刷新缓存,获取新的代理IP
- if len(self.ip_cache) < 10:
- self.refresh_proxy_ips()
- return self.ip_cache.pop()
-
- def refresh_proxy_ips(self):
- # 若IP缓存数量少于10个,则从Redis获取新的代理IP,并加入缓存
- if len(self.ip_cache) < 10:
- proxy_ips = self.redis_client.smembers('ippool')
- for ip in proxy_ips:
- self.ip_cache.append(ip.decode())
-
- def remove_proxy_ip(self, proxy_ip):
- # 从缓存中移除指定的代理IP
- if proxy_ip in self.ip_cache:
- self.ip_cache.remove(proxy_ip)
-
- def start_requests(self):
- # 启动爬虫时,若IP缓存数量少于10个,则循环刷新缓存,直到达到10个IP为止
- while len(self.ip_cache) < 10:
- self.refresh_proxy_ips()
- if len(self.ip_cache) < 10:
- time.sleep(30)
1.首先,你不能每爬一个url,就去redis里面拿一个;要是这样,你scrapy是异步抓取的,光拿ip对redis的请求就足够让你的程序爆了;
2.把ip全部放在scrapy内部缓存里面,这样提速,几十个 几百个ip,足够玩一阵子;
3.当scrapy发起请求,就拿一个ip,如果返回来的response.state有问题,就换一个ip再来一次;同时,在缓存里面,把这个失效(无用的ip)删掉;
4.当你缓存的ip少于X的时候,就再去redis里面拿ip;
5.如果redis里面的ip供应不过来,就让他等待一阵子再去拿;
--------------基本思路就是如此!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。