运用Redis和Flask动态维护IP代理池 -- 系统详解 & 代码分析

本文详述如何运用Redis和Flask搭建动态代理池系统,包括Redis服务的启动、配置,以及系统中涉及的db.py、api.py、getter.py和scheduler.py四大模块的功能解析。该系统通过抓取免费IP,存储于Redis数据库,实时监控IP质量和数量,通过Flask API提供有效IP。

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

本文针对动态代理池myProxyPool(GitHub)源码进行系统分析与代码解读,提供完整源码共大家一同交流学习,也欢迎对该项目多多指正,提出宝贵的意见~

本文涉及环境/模块/服务:

  • Python3,MacOS(本机),Linux OS(阿里云服务器/Ubuntu),Redis数据库(代理队列),Flask(API接口)

0 效果呈现

  • 远程连接阿里云服务器,运行myProxyPool目录下的 run.py文件,如图:
- 本机访问远程服务器端口`http://{host}:{port}`,三个页面显示如下(其中主页面为欢迎页面,其余依次显示当前Redis队列中代理数量以及最新可用的代理ip地址):
- 本地通过Redis图形化客户端远程连接阿里云服务器,获取当前代理ip队列的内部数据:

1 前提

1.1 项目结构

  • 通过tree -CF命令查看目录文件结构

1.2 Redis服务

1.2.1 启动Redis服务

# Step 1: 安装Redis服务
sudo apt-get install redis-server

# Step 2: 配置文件redis.conf
sudo vim /etc/redis/redis.conf

# Step 3: 读取配置文件,启动Redis服务
redis-server /etc/redis/redis.conf

# Step 4: 查看Redis服务进程
ps aux | grep "redis"

1.2.2 配置文件

  • 设置为守护进程:后台运行Redis服务
################################ GENERAL  #####################################

# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes
  • 不绑定IP地址:任何IP均可访问
# By default Redis listens for connections from all the network interfaces
# available on the server. It is possible to listen to just one or multiple
# interfaces using the "bind" configuration directive, followed by one or
# more IP addresses.
#
# Examples:
#
# bind 127.0.0.1

2 系统要求与模块间关系

2.1 动态代理池需具有的功能

  • 目前网上获取代理的方式主要分为两种——付费/免费:
    • 付费途径可以通过各家网站的api接口,获取质量较高的可用ip。但是获得ip的数量和速度与付费金额紧紧挂钩。
    • 免费途径通过网上的免费ip网站获取代理地址。但是直接从免费网站获取的ip地址往往十有八九无法使用或者已经过期,难以直接使用。
  • 本文动态代理池通过对各大免费ip网站进行代理抓取,存入Redis数据库,同时通过调度器Scheduler以多进程的方式,实时监控代理池中ip的数量和质量,从而保证代理池内的ip 维持一定的数量并且可用 。通过Flask构建API接口,使得有效的ip随取随用,并能够实时监控代理池内ip的数量。

2.2 模块间的关系

前文所述六个模块中,settings.pyerr_raise.py主要负责各服务的连接设置和异常定义,并不属于功能模块,故不在下述讨论之列。如需查看完整代码,可访问GitHub源码一起交流学习。剩下的四个模块(scheduler.py/db.py/getter.py/api.py)关系如下,结合Redis服务Flask服务,就构成了能够动态更新的ip代理池,结构图如下:

2.3 四大主要模块的功能分析

a. Redis队列的"机械手臂" – db.py

  • db.py模块处在整个系统的中心位置,与其它的任意模块都有着紧密的联系。该模块仅定义了一个RedisClient()类,该类定义了对Redis队列进行操作的几个通用方法(put()/get_for_test()/pop_for_use()等),并在其它模块当中实例化为conn对象,用于充当数据库"机械手"的角色。

b. 用户获取有效ip的"窗口" – api.py

  • api.py模块身处db.py和Flask接口之间,发挥通过python语言调用Flask服务的作用。而可用的ip代理就通过Flask服务对应的网址页面呈现出来,方便用户读取和使用。该模块比较简单,任务也比较明确直接,且没有重新定义新的class,因此代码部分在将在后文详述。

c. 批量获取待测ip的"挖掘机" – getter.py

  • 上图为getter.py模块中定义的两个class的类关系图。事实上,ProxyMetaclass作为FreeProxyGetter元类,仅仅是为了能够动态地生成两个和爬取免费ip的方法有关(后文会有详细代码分析)的两个属性。简单地看,此模块中也仅有FreeProxyGetter一个功能类
  • FreeProxyGetter类主要定义了一组以crawl_打头的爬取方法,并通过调用主方法get_raw_proxies()遍历上述爬取方法,批量爬取一系列raw_proxies,即所谓的未经有效性检测的ip代理。这些待测ip若通过下文所说的Scheduler.ValidityTester的检测,就会经由RedisClient().put()方法一次放入Redis队列当中。

d. 动态平衡的"维护者" – scheduler.py

  • ValidityTester – ip有效性测试器类,实例化为**tester对象**。
  • PoolAdder – ip池数量维护器类,实例化为**adder对象**
  • Scheduler – 调度器类,拥有两个静态方法(主体分别为testeradder),和一个run()方法开启两个并行进程,进行有效性和数量的动态维护。

3 代码解析

3.1 Redis队列的"机械手臂" – db.py

import redis
from proxypool.err_raise import PoolEmptyError
from proxypool.settings import REDIS__LIST_NAME, REDIS_HOST, REDIS_PASSWORD, REDIS_PORT


class RedisClient(object):
    """
    Redis连接类,用于连接Redis数据库并操纵其中的代理数据列表
    """
    def __init__(self, host=REDIS_HOST, port=REDIS_PORT):
        """
        连接Redis数据库
        :param host: 数据库ip地址
        :param port: 数据库端口
        """
        if REDIS_PASSWORD:
            self._db = redis.Redis(host=host, port=port, password=REDIS_PASSWORD)
        else:
            self._db = redis.Redis(host=host, port=port)

    @property
    def list_len(self):
        """
        获取队列长度
        :return: 返回队列长度
        """
        return self._db.llen(REDIS__LIST_NAME)

    def flush(self):
        """
        清空队列
        """
        self._db.flushall()

    
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值