给自己的爬虫做一个简单的动态代理池

使用代理服务器一直是爬虫防BAN最有效的手段,但网上的免费代理往往质量很低,大部分代理完全不能使用,剩下能用的代理很多也只有几分钟的寿命,没法直接用到爬虫项目中。
下面简单记录一下我用scrapy+redis实现动态代理池的过程。

我对“动态代理池” 的需求

我的爬虫项目需要7*24小时监控若干个页面,考虑了一下希望代理池能满足下面几个要求:

  • 始终保持一个相对稳定的代理数量
  • 始终保持池内代理的高可靠率(希望90%的代理都能用)
  • 尽可能减少对爬虫项目代码的更改

参考过的项目

找过一些现成的轮子,但发现或多或少都不太符合我的需求

kohn/HttpProxyMiddleware
一个“被动”选择代理的方式。在scrapy middleware中加入大量代码,让爬虫在代理失效后再去代理网站找代理,会有下面几个问题:

  • 大多数情况下始终使用一个代理去访问,造成流量集中在一个IP上,可能导致代理IP被BAN。
  • 切换代理的过程比较耗时,导致爬虫性能下降比较厉害
  • 所有逻辑都嵌套在了爬虫项目里面,有兼容性和可移植性方面的问题(有多个爬虫的话每个都要改一遍..)
  • 基于python2写的,我的项目在python3上..

jhao104/proxy_pool
这个几乎和我想要的一样,但还是因为下面几点原因没有使用:

  • 基于SSDB,这边没有现成的SSDB,因为已经在用Redis了不想专门去装一个
  • 只管定时收集代理,在收集过程中做一次验证。但事实上收集到的代理即便通过了验证,也可能活不过10分钟,时间一长代理池内就会有很多过期的代理,需要在爬虫代码中处理这些过期代理(爬虫代码调用delete删除)。

设计思路和代码

看了那么多方案,我就在想:能不能让代理池具有自我检查自我修复的功能?这样我们的爬虫就只需随机拿一个代理用就可以了,就算恰巧拿到一个失效代理,只要做一次retry,代理池的修复机制可以保证retry的时候失效的代理已经被移走了,不会再次取到。

简单规划一下:

  • 我们需要一个自检程序,它每10S跑一次,保证代理池内所有代理至少在10S内有效
  • 我们需要一个代理获取的程序,当代理池内代理数量过低时(阈值定为<5),访问免费代理网站补充新代理
  • 我们需要一个调度程序,用来监控代理池数量并调用上面两个程序,维持代理池平衡。
  • 作为私有代理池就维护在redis了(SET),让爬虫直接从redis里取代理。

对应的代码就有这么三个部分:

  • 一个scrapy爬虫去爬代理网站,获取免费代理,验证后入库 (proxy_fetch)
  • 一个scrapy爬虫把代理池内的代理全部验证一遍,若验证失败就从代理池内删除 (proxy_check)
  • 一个调度程序用于管理上面两个爬虫 (start.py)

强行画个流程图:

hq-proxies.png

爬虫部分全部用scrapy写了,其实没必要,用requests就够了..但做的时候刚学scrapy,就顺便练练手了..
start.py的调度方式比较粗暴,直接起两个线程,在线程内用os.system调用scrapy爬虫(毕竟轻量级代理池嘛..好吧其实就是我懒图个方便..)

另外还有几个调度策略需要说一下:

  • 每次调用proxy_fetch后会自动设定一个“保护时间”10分钟,在保护期内除非代理池只剩一个代理了,否则不会触发proxy_fetch,避免频繁调用。
  • 加入了一个“刷新时间”24小时,保证每24小时内至少执行proxy_fetch一次
  • 验证程序设定timeout为5秒,5秒内没访问到测试页面就认为验证失败

其他细节可以看源码:arthurmmm/hq-proxies

部署和使用

需要先改一下配置文件hq-proxies.yml,把Redis的地址密码之类的填上,改完后放到/etc/hq-proxies.yml下。
在配置文件中也可以调整相应的阈值和免费代理源和测试页面。
测试页面需要频繁访问,为了节省流量我在某云存储上丢了个helloworld的文本当测试页面了,云存储有流量限制建议大家换掉。。验证方式很粗暴,比较一下网页开头字符串。。

另外写了个Dockerfile可以直接部署到Docker上(python3用的是Daocloud的镜像),跑容器的时候记得把hq-proxies.yml映射到容器/etc/hq-proxies.yml下。
手工部署的话跑pip install -r requirements.txt安装依赖包

在scrapy中使用代理池的只需要添加一个middleware,每次爬取时从redis SET里用srandmember随机获取一个代理使用,代理失效和一般的请求超时一样retry,代理池的自检特性保证了我们retry时候再次拿到失效代理的概率很低。middleware代码示例:

class DynamicProxyMiddleware(object):
    def process_request(self, request, spider):
        redis_db = StrictRedis(
            host=LOCAL_CONFIG['REDIS_HOST'], 
            port=LOCAL_CONFIG['REDIS_PORT'], 
            password=LOCAL_CONFIG['REDIS_PASSWORD'],
            db=LOCAL_CONFIG['REDIS_DB']
        ) 
        proxy = redis_db.sismember(PROXY_SET, proxy):
        logger.debug('使用代理[%s]访问[%s]' % (proxy, request.url))
        request.meta['proxy'] = proxy

在其他爬虫框架下使用也是类似的。

最后放一张萌萌哒日志菌触发proxy_fetch时候的截图:

Paste_Image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 1 前言 作为一名合格的数据分析师,其完整的技术知识体系必须贯穿数据获取、数据存储、数据提取、数据分析、数据挖掘、...
    whenif阅读 17,988评论 45 523
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • 风险分为不同的层次面,我们现阶段可分为规避,降低,自留。 工作中不可避免的人员去留,相对表现通过观察与沟通提前做好...
    杨平的阅读 250评论 0 0
  • 企业所有的制度出台一定有它独特的缘由,企业各项规章制度是企业的内部法规, 是企业日常管理行为的重要依据,它可...
    YY的世界阅读 519评论 2 1
  • 今天参加了一个世界诗歌日的朗诵活动。诗歌配春雨,不错。 分享一下我的自选诗歌。 推荐一个APP,为你读诗。
    寒晗Tylor阅读 213评论 0 3