博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Redis+Flask维护动态代理池
阅读量:7050 次
发布时间:2019-06-28

本文共 2823 字,大约阅读时间需要 9 分钟。

目标

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

为什么要用代理池?

  • 许多网站有专门的反爬虫措施,可能遇到封IP等问题。
  • 互联网上公开了大量免费代理,利用好资源。
  • 通过定时的检测维护同样可以得到多个可用代理。

代理池的要求?

  • 多站抓取,异步检测
  • 定时筛选,持续更新
  • 提供接口,易于提取

代理池架构?

Requests+%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%88%AC%E5%8F%96%E7%8C%AB%E7%9C%BC%E7%94%B5%E5%BD%B1-1.png

代理池的实现

项目完整代码已托管到github:

项目结构如下:

%E4%BD%BF%E7%94%A8Redis+Flask%E7%BB%B4%E6%8A%A4%E5%8A%A8%E6%80%81%E4%BB%A3%E7%90%86%E6%B1%A0-2.png

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

from proxypool.api import appfrom proxypool.schedule import Scheduledef 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, gfrom .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.cnblogs.com/woyouyihujiu/p/10035570.html

你可能感兴趣的文章
<转>ThinkPHP的开发常用系统配置项
查看>>
真正的让iframe自适应高度 兼容多种浏览器随着窗口大小改变
查看>>
大数据多维分析平台的实践
查看>>
Python常用函数
查看>>
二分法习题HDU2199
查看>>
strcpy,sprintf,memcpy的区别
查看>>
web框架
查看>>
线程互斥锁
查看>>
spring colud 博客
查看>>
Redis安装
查看>>
JavaScript 自学过程
查看>>
GDAL源码剖析(三)之Swig编译和帮助文档生成
查看>>
Android学习笔记:NDK入门一些总结
查看>>
Project Euler Problem 3: Largest prime factor
查看>>
颜色区分
查看>>
微信认证结果拆分为资质审核和名称审核
查看>>
Sass和Compass入门
查看>>
重装系统后删除Cygwin文件夹
查看>>
享元模式
查看>>
M4修改外部晶振8M和25M晶振的方法
查看>>