Python-进行代理池的维护

本文介绍了如何使用Python建立一个代理池系统,包括设置初始数据、异常处理、存储模块、爬虫抓取、代理获取、检测与接口模块。通过运行调度模块,可以从代理池中随机获取可用的HTTP代理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用python创建自己的代理池,可以自己以后使用。

初始数据

proxypool.setting

# Redis数据库地址
REDIS_HOST = '127.0.0.1'

# Redis端口
REDIS_PORT = 6379

# Redis密码,如无填None
REDIS_PASSWORD = None

REDIS_KEY = 'proxies'

# 代理分数,最高为100分,最低我0分。初始分数为10分
MAX_SCORE = 100
MIN_SCORE = 0
INITIAL_SCORE = 10

# 有效的状态码
VALID_STATUS_CODES = [200, 302]

# 代理池数量界限
POOL_UPPER_THRESHOLD = 50000

# 检查周期
TESTER_CYCLE = 20
# 获取周期
GETTER_CYCLE = 300

# 测试API,建议抓哪个网站测哪个,这里用百度网来测试API
TEST_URL = 'http://www.baidu.com'

# API配置,API地址、端口
API_HOST = '0.0.0.0'
API_PORT = 5555

# 开关
TESTER_ENABLED = True
GETTER_ENABLED = True
API_ENABLED = True

# 最大批测试量
BATCH_TEST_SIZE = 10

异常问题

proxypool.error

class PoolEmptyError(Exception):

    def __init__(self):
        # Exception类,是所有非退出异常的公共基类。
        Exception.__init__(self)

    def __str__(self):
        # repr函数,返回对象的规范字符串表示形式。
        return repr('代理池已经枯竭')

存储模块

proxypool.db

import redis
from proxypool.error import PoolEmptyError
from proxypool.setting import REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_KEY
from proxypool.setting import MAX_SCORE, MIN_SCORE, INITIAL_SCORE
from random import choice
import re


class RedisClient(object):
    def __init__(self, host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD):
        """
        初始化
        :param host: Redis 地址
        :param port: Redis 端口
        :param password: Redis密码
        """
        # 创建链接数据库对象
        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: 添加结果
        """
        # zscore() 方法,返回 "REDIS_KEY" 中元素为 "proxy" 的分数。
        # zadd() 方法,将任意数量的元素名称、分数对设置为键 "REDIS_KEY"。
        if not re.match('\d+\.\d+\.\d+\.\d+\:\d+', proxy):
            print('代理不符合规范', proxy, '丢弃')
            return
        if not self.db.zscore(REDIS_KEY, proxy):
            return self.db.zadd(REDIS_KEY, score, proxy)
    
    def random(self):
        """
        从数据库中随机获取有效代理,首先尝试获取最高分数代理,如果不存在,按照排名获取,否则异常
        :return: 随机代理
        """
        # zrangebyscore() 方法,返回排序集 "REDIS_KEY" 中带分数的值,其中分数范围为 MAX_SCORE ~ MAX_SCORE ,即返回 100 分的代理
        # 代理的有效程度以分数来区分,分数高,说明代理越稳定。
        # 首先查找 100 分的代理,如果没有,则在 0 ~ 100 之间查找最高分的代理,
        # 如果还没有,则调用 proxypool.error.PoolEmptyError 抛出异常
        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: 修改后的代理分数
        """
        # zscore() 方法,返回 "REDIS_KEY" 中元素为 "proxy" 的分数。
        # zincrby() 方法,按 “-1” 增加排序集 "REDIS_KEY" 中 "proxy" 的分数
        # zrem() 方法,从排序集 "REDIS_KEY" 中删除成员 "proxy"
        score = self.db.zscore(REDIS_KEY, proxy)
        if score and score > MIN_SCORE:
            print('代理', proxy, '当前分数', score, '减1')
            return self.db.zincrby(REDIS_KEY, proxy, -1)
        else:
            print('代理', proxy, '当前分数', score, '移除')
            return self.db.zrem(REDIS_KEY, proxy)
    
    def exists(self, proxy):
        """
        判断是否存在
        :param proxy: 代理
        :return: 是否存在
        """
        # zscore() 方法,返回 "REDIS_KEY" 中元素为 "proxy" 的分数。
        return not self.db.zscore(REDIS_KEY, proxy) == None
    
    def max(self, proxy):
        """
        将代理设置为MAX_SCORE
        :param proxy: 代理
        :return: 设置结果
        """
        print('代理', proxy, '可用,设置为', MAX_SCORE)
        # zadd() 方法,将任意数量的元素名称、分数对设置为键 "REDIS_KEY"。
        return self.db.zadd(REDIS_KEY, MAX_SCORE, proxy)
    
    def count(self):
        """
        获取数量
        :return: 数量
        """
        # zcard() 方法,返回排序集 "REDIS_KEY" 中的元素个数
        return self.db.zcard(REDIS_KEY)
    
    def all(self):
        """
        获取全部代理
        :return: 全部代理列表
        """
        # zrangebyscore()方法,获取 MIN_SCORE ~ MAX_SCORE 的代理,即所有代理
        return self.db.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值