资讯专栏INFORMATION COLUMN

使用Redis+Flask维护动态代理池

vibiu / 2757人阅读

摘要:目标爬虫中经常遇到被封杀的情况最有效的方式就是使用代理。为什么要用代理池许多网站有专门的反爬虫措施,可能遇到封等问题。通过定时的检测维护同样可以得到多个可用代理。

目标

爬虫中经常遇到被封杀IP的情况,最有效的方式就是使用代理IP。我们可以在一些平台上购买代理IP,但是价格比较昂贵。另外很多IP代理网站也提供了一些免费的代理IP,可以爬取下这些代理IP,并使用webAPI方式提供代理IP服务。

为什么要用代理池?

许多网站有专门的反爬虫措施,可能遇到封IP等问题。

互联网上公开了大量免费代理,利用好资源。

通过定时的检测维护同样可以得到多个可用代理。

代理池的要求?

多站抓取,异步检测

定时筛选,持续更新

提供接口,易于提取

代理池架构?

代理池的实现
项目完整代码已托管到github:https://github.com/panjings/p...

项目结构如下:

从程序的入口run.py开始分析:

from proxypool.api import app
from proxypool.schedule import Schedule

def main():
    
    s = Schedule()
    // 运行调度器
    s.run()
    // 运行接口
    app.run()

if __name__ == "__main__":
    main()

run.py中不难看出,首先运行了一个调度器,接着运行了一个接口。

调度器schedule.py代码:

class Schedule(object):
    @staticmethod
    def valid_proxy(cycle=VALID_CHECK_CYCLE):
        """
        Get half of proxies which in redis
        """
        conn = RedisClient()
        tester = ValidityTester()
        while True:
            print("Refreshing ip")
            count = int(0.5 * conn.queue_len)
            if count == 0:
                print("Waiting for adding")
                time.sleep(cycle)
                continue
            raw_proxies = conn.get(count)
            tester.set_raw_proxies(raw_proxies)
            tester.test()
            time.sleep(cycle)

    @staticmethod
    def check_pool(lower_threshold=POOL_LOWER_THRESHOLD,
                   upper_threshold=POOL_UPPER_THRESHOLD,
                   cycle=POOL_LEN_CHECK_CYCLE):
        """
        If the number of proxies less than lower_threshold, add proxy
        """
        conn = RedisClient()
        adder = PoolAdder(upper_threshold)
        while True:
            if conn.queue_len < lower_threshold:
                adder.add_to_queue()
            time.sleep(cycle)

    def run(self):
        print("Ip processing running")
        valid_process = Process(target=Schedule.valid_proxy)
        check_process = Process(target=Schedule.check_pool)
        valid_process.start()
        check_process.start()

Schedule中首先声明了valid_proxy(),用来检测代理是否可用,其中ValidityTester()方法中的test_single_proxy()方法是实现异步检测的关键。
接着check_pool()方法里面传入了三个参数:两个代理池的上下界限,一个时间。其中PoolAdder()add_to_queue()方法中使用了一个从网站抓取ip的类FreeProxyGetter()FreeProxyGetter()定义在getter.py里面。

接口api.py的代码:

from flask import Flask, g

from .db import RedisClient

__all__ = ["app"]

app = Flask(__name__)


def get_conn():
    """
    Opens a new redis connection if there is none yet for the
    current application context.
    """
    if not hasattr(g, "redis_client"):
        g.redis_client = RedisClient()
    return g.redis_client


@app.route("/")
def index():
    return "

Welcome to Proxy Pool System

" @app.route("/get") def get_proxy(): """ Get a proxy """ conn = get_conn() return conn.pop() @app.route("/count") def get_counts(): """ Get the count of proxies """ conn = get_conn() return str(conn.queue_len) if __name__ == "__main__": app.run()

不难看出,在api.py中利用了flask框架的特性定义了各种接口。

具体代码实现请参考github。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42764.html

相关文章

  • Python3网络爬虫实战---6、Web库的安装:Flask、Tornado

    摘要:在本书中用到的一些服务程序主要有。本节来分别介绍它们的安装方法。的安装是一个轻量级的服务程序,简单易用灵活,在本书中我们主要用它来做一些服务,本节我们来了解下它的安装方式。相关链接官方文档安装执行完毕之后即可完成安装。 上一篇文章:Python3网络爬虫实战---5、存储库的安装:PyMySQL、PyMongo、RedisPy、RedisDump下一篇文章:Python3网络爬虫实战-...

    yeyan1996 评论0 收藏0
  • 使用代理处理反爬抓取微信文章

    摘要:目标使用代理反爬抓取微信文章,获取文章标题内容公众号等信息,并存储到数据库中。代理设置在使用维护动态代理池一文中,我们讲解了代理池的基本原理和简单实现,代码已托管到上,现在让我们利用代理池来获取随机代理。 目标 使用代理反爬抓取微信文章,获取文章标题、内容、公众号等信息,并存储到MongoDB数据库中。 流程框架 如果要抓取微信公众号文章可以使用搜狗的搜索引擎,它会显示最新的文章,但是...

    QiShare 评论0 收藏0
  • 面向对象的分布式爬虫框架XXL-CRAWLER

    摘要:面向对象的分布式爬虫框架一简介概述是一个面向对象的分布式爬虫框架。分布式集群集群方式维护爬虫爬虫运行数据,可通过或定制实现。 《面向对象的分布式爬虫框架XXL-CRAWLER》 showImg(https://segmentfault.com/img/remote/1460000011842697);showImg(https://segmentfault.com/img/remote...

    anquan 评论0 收藏0
  • Python-爬虫工程师-面试总结

    摘要:内存池机制提供了对内存的垃圾收集机制,但是它将不用的内存放到内存池而不是返回给操作系统。为了加速的执行效率,引入了一个内存池机制,用于管理对小块内存的申请和释放。 注:答案一般在网上都能够找到。1.对if __name__ == main的理解陈述2.python是如何进行内存管理的?3.请写出一段Python代码实现删除一个list里面的重复元素4.Python里面如何拷贝一个对象?...

    antz 评论0 收藏0

发表评论

0条评论

vibiu

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<