【Python】爬虫实战-基于代理池的高并发爬虫
最近在写一个基于代理池的高并发爬虫,目标是用单机从某网站 API 爬取十亿级别的JSON数据。
代理池
有两种方式能够实现爬虫对代理池的充分利用:
- 搭建一个 Tunnel Proxy 服务器维护代理池
- 在爬虫项目内部自动切换代理
所谓 Tunnel Proxy 实际上是将切换代理的操作交给了代理服务器,很多市面上的代理软件都有此类功能。
如果要自行搭建可参考以下项目:
考虑到高并发,在爬虫项目内部切换代理更加灵活一些。代理池选一个能用的就行:GitHub - jhao104/proxy_pool
记得加上匿名校验:能否设置代理池只获取高匿IP · Issue #169 · jhao104/proxy_pool · GitHub
代理切换策略
如果简单的在多线程中对每个 requests.get() 使用不同的代理,那么一定会遇到内存泄露的问题:
- 内存泄露问题 · Issue #522 · jhao104/proxy_pool · GitHub
- Requests memory leak · Issue #4601 · psf/requests · GitHub
- Memory Leak in Python requests - GeeksforGeeks
即便写成:
session = requests.session()
response = session.get(url, headers=headers, proxies=proxies)
response.close()
session.close()
甚至在加上 gc.collect() 也无济于事。
因此需要控制创建 session 对象的数量,只在请求失败后切换代理和创建新的 session。
工作流程
① 主线程根据 URL 数量动态创建子进程,虚线框内为子进程任务
② crawler_task 为线程任务,执行发送请求和解析JSON
插入策略
每个子进程维护一个 url_queue 和 insert_queue。
线程会从 url_queue 取出URL执行爬取任务,由于JSON数据占用的空间不大,所以线程会先将每个 response 经过简单解析后存到列表中。
等到 url_queue 为空时(不要使用不安全的 queue.empty() 判断),get 方法会触发 Timeout 异常,然后线程会将列表插入到 insert_queue 中。
所有线程任务结束后,子进程再执行 executemany 将数据批量插入到 MySQL。
其他
爬取JSON数据产生的流量不大,但需要考虑 PPS(packet per second),如果网络设施不到位的话可能严重影响爬取效率。
网络上获取的免费代理大多是透明代理,如果使用开源项目 Proxy_Pool 作为代理池并加入匿名校验,可能会间歇性导致代理池没有可用代理。(所以最好还是从一些网络空间测绘引擎上通过特征抓取)
原文地址:https://www.cnblogs.com/victorique-de-blois/p/17075801.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 设计模式之抽象工厂模式
- 微信小游戏的环境搭建
- 威胁事件告警分析技巧及处置(一)
- docker数据卷备份恢复以及配置桥接网络
- ES对磁盘的要求都有哪些,大部分你可能不知道
- docker通过模板创建镜像以及容器、仓库和数据管理
- Form表单类组件与Map地图组件
- 转录组分析 | 使用Hisat2进行序列比对
- 最后一个页面:构建电影详情页面
- 安装docker以及通过容器创建镜像
- 转录组分析 | 使用trim-galore去除低质量的reads和adaptor
- 设计模式之工厂方法模式
- Ubuntu上安装TensorFlow(python2.7版)
- 转录组分析 | fastqc进行质控与结果解读
- playbook管理配置文件