使用代理服务器一直是爬虫防BAN最有效的手段,但网上的免费代理往往质量很低,大部分代理完全不能使用,剩下能用的代理很多也只有几分钟的寿命,没法直接用到爬虫项目中。

下面简单记录一下我用scrapy+redis实现动态代理池的过程。

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

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

始终保持一个相对稳定的代理数量

始终保持池内代理的高可靠率(希望90%的代理都能用)

尽可能减少对爬虫项目代码的更改

参考过的项目

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

kohn/

大多数情况下始终使用一个代理去访问,造成流量集中在一个IP上,可能导致代理IP被BAN。

切换代理的过程比较耗时,导致爬虫性能下降比较厉害

所有逻辑都嵌套在了爬虫项目里面,有兼容性和可移植性方面的问题(有多个爬虫的话每个都要改一遍..)

基于python2写的,我的项目在python3上..

jhao104/

基于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秒内没访问到测试页面就认为验证失败

部署和使用

需要先改一下配置文件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

python ip动态代理_给自己的爬虫做一个简单的动态代理池相关推荐

  1. Python【小游戏合集】之自己做一个简单又好玩的推箱子小游戏

    导语:哈喽铁汁们~今日游戏之旅开始! 想领取完整源码跟python学习资料可私信我或点击这行字体 这期就是带大家使用当前主流且易用的Python语言做一个简单的推箱子小游戏 现在小编的快乐源泉就是玩自 ...

  2. python tkinter计算器实例_利用Tkinter(python3.6)实现一个简单计算器

    前言 上机实践课程开始了,嗯,老师来了之后念了下PPT,然后说:开始做吧......... 然后就开始了Python的GUI之路,以前没接触过PYthon的可视化界面(虽然这样很不明智) 但是现在做起 ...

  3. python爬虫系列:做一个简单的动态代理池

    自动 1.设置动态的user agent 1 import urllib.request as ure 2 import urllib.parse as upa 3 import random 4 f ...

  4. clistctrl控件最后插入在后面_用图表控件做一个简单的员工信息查询系统

    前几天在上课的时候有同学说在做人员的信息查询的时候,经常的要去做查找搜索很麻烦,能不能做一个简单的人员信息查询系统,只需要选择人员的编号就可以查询到这个员工的信息.其实要实现这个同学的需求在EXCEL ...

  5. 安卓 spinner下拉框 做模糊查询_用图表控件做一个简单的员工信息查询系统

    前几天在上课的时候有同学说在做人员的信息查询的时候,经常的要去做查找搜索很麻烦,能不能做一个简单的人员信息查询系统,只需要选择人员的编号就可以查询到这个员工的信息.其实要实现这个同学的需求在EXCEL ...

  6. 用c语言简单办法做一个字典_如何用c语言做一个简单的英语词典

    展开全部 //新建一个字典文本文件,命名为:dict.dat,内容格式如下: 或下载一个也可 //abandon v.抛弃,放32313133353236313431303231363533e59b9 ...

  7. 一个表字段做为表名_在冬天,安心做一个简单知足的人 |为你读诗

    知足的快乐,其实才是拥有|第2670期 双十一年卡会员特惠福利 限时268元,再加赠128元<为你读诗第二辑> 时间截至11月11日24:00 ▾  点击收听  ▾是这样的:你曾快乐 作者 ...

  8. 使用ANTLR做一个简单的Python SQL语法解析器 - 推酷

    使用ANTLR做一个简单的Python SQL语法解析器 - 推酷 使用ANTLR做一个简单的Python SQL语法解析器 - 推酷 posted on 2016-11-14 13:11 lexus ...

  9. python自己做个定时器_技术图文:如何利用 Python 做一个简单的定时器类?

    原标题:技术图文:如何利用 Python 做一个简单的定时器类? 背景 今天在B站上看有关 Python 最火的一个教学视频 -- "零基础入门学习 Python",这也是我们 P ...

最新文章

  1. 【译】A Brief History of P2P Content Distribution, in 10 Major Steps
  2. 汇编语言---计算表达式的值
  3. Idea加快开发的10个技巧
  4. IP记录Linux所有用户操作日志的方法(附脚本)
  5. 修改10g自动统计信息收集作业GATHER_STATS_JOB到仅仅周末执行
  6. 另类多线程生产者与消费者模式
  7. Cloud Foundry 2018欧盟峰会日程已确定
  8. xshell、xftp官方免费版下载
  9. 【ARC112F】Die Siedler(根号分治)(bfs)
  10. 只有程序员能听懂的笑话【关于TCP的链接的笑话】
  11. 【华为OD机试真题 Java】找出通过车辆最多颜色 (A卷2022Q4)
  12. Python基础--魔法方法()运算符重载)
  13. java服务器如何群发消息,java TCP编程简单实现一个消息群发功能
  14. Win10 盘符更改后需要修改的
  15. STC89C52RC/RD中定时器2的使用方法
  16. 语言学c刊,完整版|最新版C刊(2021-2022版)目录发布!新增和踢出了哪些?
  17. 计算机视觉实验室(China)
  18. 固定资产的主要包括哪些
  19. 关于深度学习方面的一些概念
  20. Video4Linux下USB摄像头驱动和视频采集的实现

热门文章

  1. 023. 我有一只大黑狗
  2. 小程序设计规范(一)
  3. powershell下使用linux命令,PowerShell-PowerShell(命令行脚本工具)下载 v7.0.3官方版--pc6下载站...
  4. I2C通信之EEPROM
  5. 推荐几个代码自动生成器
  6. Openstack:创建实例
  7. 在WIN2003以及WIN2000 SERVER下使用pqmagic
  8. 小程序wxParse的使用
  9. kubernetes devops java 模板
  10. 虚拟交易正在成为网上淘金者的下一个盛宴