python爬虫-自建IP代理池

本文介绍了如何自建Python代理池,包括存储、获取、检测和接口四个模块。存储模块利用Redis有序集合管理代理,获取模块定时抓取代理并存储,检测模块通过异步请求检测代理有效性,接口模块提供Web API服务。文章还详细讲解了各模块的实现细节和调度模块的运行方式。
摘要由CSDN通过智能技术生成
写在前面

最近跟静觅大神学习了维护代理池
就借此机会整理一下

整体思路

代理池主要分为4个模块:存储模块、获取模块、检测模块、接口模块

  • 存储模块:使用Redis有序集合,用来做代理的去重和状态标识
  • 获取模块:定时从代理网站获取代理,将获取的代理传递给存储模块,并保存到数据库
  • 检测模块:定时通过存储模块获取所有代理,并对代理进行检测,根据不同的检测结果对代理设置不同的标识
  • 接口模块:通过Web API提供服务接口,接口通过连接数据库并通过Web形式返回可用代理
    接下来,就一一实现这些模块吧。
存储模块

这里我们使用Redis的有序集合,集合的每一个元素都是不重复的。另外,有序集合的每一个元素都有一个分数字段。
对于代理池来说,这个分数可以作为判断一个代理是否可用的标志,100为最高分,代表最可用;0为最低分,代表不可用。
如果要获取代理,可以从代理池中随机获取分数最高的代理。

分数的设置规则:新获取的代理的分数为10,如果测试可行,分数立即置为100,检测到不可用就将分数减1,分数减至0后代理移除。

具体代码实现如下(ippool_save.py)

MAX_SCORE = 100 #最高分
MIN_SCORE = 0 #最低分
INITIAL_SCORE = 10  #初始分数
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_PASSWORD = None
REDIS_KEY = 'proxies' #键名

import redis
from random import choice

class PoolEmptyError():
    def __str__(self):
        return PoolEmptyError

class RedisClient(object):
    def __init__(self,host=REDIS_HOST,port=REDIS_PORT,password=REDIS_PASSWORD):
        '''
        初始化
        :param host:地址
        :param port: 端口号
        :param password: 密码
        '''
        self.db = redis.StrictRedis(host=host,port=port,password=password,decode_responses=True)

    def add(self,proxy,score=INITIAL_SCORE):
        '''
        添加代理,设置初始分数
        :param proxy: 代理
        :param score: 分数
        :return: 添加结果
        '''
        if not self.db.zscore(REDIS_KEY,proxy):
            return self.db.zadd(REDIS_KEY,{
   proxy:score})

    def random(self):
        '''
        随即获取有效代理,首先尝试获取最高分数代理,如果最高分数不存在,则按照排名获取
        :return:
        '''
        result = self.db.zrangebyscore(REDIS_KEY,MAX_SCORE,MAX_SCORE)
        if len(result):
            return choice(result)
        else:
            result = self.db.zrevrange(REDIS_KEY,0,100)
            if len(result):
                return choice(result)
            else:
                raise PoolEmptyError

    def decrease(self, proxy):
        '''
        代理值减一分,分数小于最小值,则代理删除
        :param proxy: 代理
        :return: 修改后的代理分数
        '''
        score = self.db.zscore(REDIS_KEY,proxy)
        if score and score>MIN_SCORE:
            print("代理",proxy,"当前分数",score,"减1")
            return self.db.zincrby(REDIS_KEY,-1,proxy)
        else:
            print("代理",proxy,"当前分数",score,"移除")
            return self.db.zrem(REDIS_KEY,proxy)

    def exists(self,proxy):
        '''
        判断是否存在
        :param proxy: 代理
        :return: 是否存在
        '''
        return not self.db.zscore(REDIS_KEY,proxy) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值