您的位置: 首页 > 新闻资讯 > 正文

代理IP爬虫知乎过程

发布时间:2019-11-15 15:11:12 来源:

想要用代理IP爬取知乎网站?知乎的发爬策略一旦并发过大就会限制你。所以,我们如果要爬知乎,那么设置代理跟UA是必要操作。黑洞代理下面分享爬取的主要环节部分给大家:

代理IP爬虫知乎过程

在中间件middlewares.py中写入下面的代码:

class RandomProxy(object):

def __init__(self):

self.current_proxy = None

self.lock = DeferredLock()

def process_request(self, request, spider):

user_agent = random.choice(USER_AGENT_LIST)

request.headers['User-Agent'] = user_agent

if 'proxy' not in request.meta or self.current_proxy.is_expiring:

# 请求代理

self.update_proxy()

request.meta['proxy'] = self.current_proxy.proxy

def process_response(self, request, response, spider):

# 如果对方重定向(302)去验证码的网页,换掉代理IP

# 'captcha' in response.url 指的是有时候验证码的网页返回的状态码是200,所以用这个作为辨识的标志

if response.status != 200 or 'captcha' in response.url:

# 如果来到这里,说明这个请求已经被boss直聘识别为爬虫了

# 所以这个请求就相当于什么都没有获取到

# 所以要重新返回request,让这个请求重新加入到调度中

# 下次再发送

if not self.current_proxy.blacked:

self.current_proxy.blacked = True

self.update_proxy()

print('%s代理失效' % self.current_proxy.proxy)

request.meta['proxy'] = self.current_proxy.proxy

return request

# 如果是正常的话,记得最后要返回response

# 如果不返回,这个response就不会被传到爬虫那里去

# 也就得不到解析

return response

def update_proxy(self):

# lock是属于多线程中的一个概念,因为这里scrapy是采用异步的,可以直接看成多线程

# 所以有可能出现这样的情况,爬虫在爬取一个网页的时候,忽然被对方封了,这时候就会来到这里

# 获取新的IP,但是同时会有多条线程来这里请求,那么就会出现浪费代理IP的请求,所以这这里加上了锁

# 锁的作用是在同一时间段,所有线程只能有一条线程可以访问锁内的代码,这个时候一条线程获得新的代理IP

# 而这个代理IP是可以用在所有线程的,这样子别的线程就可以继续运行了,减少了代理IP(钱)的浪费

self.lock.acquire()

# 判断换线程的条件

# 1.目前没有使用代理IP

# 2.到线程过期的时间了

# 3.目前IP已经被对方封了

# 满足以上其中一种情况就可以换代理IP了

if not self.current_proxy or self.current_proxy.is_expiring or self.current_proxy.blacked:

# 豌豆生成的api,但是太慢了

url = r'http://api.wandoudl.com/api/ip?app_key=b976ddb549fe800a35750b30d82b67c2&pack=0&num=20&xy=1&type=2&lb=\r\n&mr=1&'

response = requests.get(url=url, headers=DEFAULT_REQUEST_HEADERS)

text = json.loads(response.text)

data = text['data'][0]

proxy_model = ProxyModel(data)

print('重新获取了一个代理:%s' % proxy_model.proxy)

self.current_proxy = proxy_model

# return proxy_model

self.lock.release()

在新建一个py文件放入下面的代码:

from datetime import datetime, timedeltaclass ProxyModel(object): def __init__(self, data): self.ip = data['ip'] self.port = data['port'] self.expire_str = data['expire_time'] self.proxy = 'http://' + '%s:%s' % (self.ip, self.port) self.expire_time = self.detail_time # 代理是否已经被拉入黑名单了 self.blacked = False # 这个函数用于把str格式的过期时间(expire_time)转化为datetime格式,方便我们来 # 根据过期时间换新的代理 @property def detail_time(self): date_str, time_str = self.expire_str.split(" ") year, month, day = date_str.split('-') hour, minute, second = time_str.split(':') expire_time = datetime( year=int(year), month=int(month), day=int(day), hour=int(hour), minute=int(minute), second=int(second), ) return expire_time # 比较代理的过期时间和现在的时间 # 如果这个代理的存活时间少于10,那么就要准备更换代理IP了 @property def is_expiring(self): now = datetime.now() if (self.expire_time - now) < timedelta(seconds=10): return True else: return False

到这配置基本就结束了。在setting.py中修改下面的代码:

DOWNLOADER_MIDDLEWARES = { # 'zhihuscrapy.middlewares.ZhihuscrapyDownloaderMiddleware': 543, 'zhihuscrapy.middlewares.RandomProxy': 100,}

操作到这里就完全结束,启动项目就会发现请求是从代理IP发出的。

如果大家有需要选择优质的代理IP,那么黑洞代理的IP质量非常不错,可以帮助大家进行任何爬虫项目。


相关文章内容简介

1 代理IP爬虫知乎过程

  想要用代理IP爬取知乎网站?知乎的发爬策略一旦并发过大就会限制你。所以,我们如果要爬知乎,那么设置代理跟UA是必要操作。黑洞代理下面分享爬取的主要环节部分给大家:  在中间件middlewares.py中写入下面的代码:  class∵RandomProxy(object):  def∵__init__(self):  self.current_proxy∵=∵None  self.lock∵=∵DeferredLock()  def∵process_request(self,∵request,... [阅读全文]