送你一款Python异步爬虫代理池!超级实用!已开源!

匿名 (未验证) 提交于 2019-12-02 22:54:36

项目地址

https : //github.com/chenjiandongx/async-proxy-pool 

Async Proxy Pool

异步爬虫代理池,以 Python asyncio 为基础,旨在充分利用 Python 的异步性能。

配置文件

配置文件 config.py,保存了项目所使用到的所有配置项。如下所示,用户可以根据需求自行更改。不然按默认即可。

总体架构

项目主要几大模块分别是爬取模块,存储模块,校验模块,调度模块,接口模块。


  • 爬取模块 负责爬取代理网站,并将所得到的代理存入到数据库,每个代理的初始化权值为 INIT_SCORE。
  • 存储模块 封装了 Redis 操作的一些接口,提供 Redis 连接池。
  • 校验模块 验证代理 IP 是否可用,如果代理可用则权值 +1,最大值为 MAX_SCORE。不可用则权值 -1,直至权值为 0 时将代理从数据库中删除。
  • 调度模块 负责调度爬取器和校验器的运行。
  • 接口模块 使用 sanic 提供 WEB API 。

返回指定数量的代理,权值从大到小排序。

$ http http: //localhost:3289/get/10 HTTP/ 1.1   200  OK Connection : keep-alive Content - Length :  393 Content - Type : application/json Keep - Alive :  5 [  {   "http" :  "http://94.177.214.215:3128"  },  {   "http" :  "http://94.139.242.70:53281"  },  {   "http" :  "http://94.130.92.40:3128"  },  {   "http" :  "http://82.78.28.139:8080"  },  {   "http" :  "http://82.222.153.227:9090"  },  {   "http" :  "http://80.211.228.238:8888"  },  {   "http" :  "http://80.211.180.224:3128"  },  {   "http" :  "http://79.101.98.2:53281"  },  {   "http" :  "http://66.96.233.182:8080"  },  {   "http" :  "http://61.228.45.165:8080"  } ] 

/count

返回代理池中所有代理总数

$ http http: //localhost:3289/count HTTP/ 1.1   200  OK Connection : keep-alive Content - Length :  15 Content - Type : application/json Keep - Alive :  5 {   "count" :  "698" } 

/count/<score:int>

返回指定权值代理总数

$ http http: //localhost:3289/count/10 HTTP/ 1.1   200  OK Connection : keep-alive Content - Length :  15 Content - Type : application/json Keep - Alive :  5 {   "count" :  "143" } 

/clear/<score:int>

删除权值小于等于 score 的代理

$ http http: //localhost:3289/clear/0 HTTP/ 1.1   200  OK Connection : keep-alive Content - Length :  22 Content - Type : application/json Keep - Alive :  5 {   "Clear" :  "Successful" } 

扩展爬取网站

在 crawler.py 文件里新增你自己的爬取方法。

class   Crawler :   @staticmethod   def  run():  ...   # 新增你自己的爬取方法   @staticmethod   @collect_funcs   # 加入装饰器用于最后运行函数   def  crawl_xxx():   # 爬取逻辑 

sanic 性能测试

使用 wrk 进行服务器压力测试。基准测试 30 秒, 使用 12 个线程, 并发 400 个 http 连接。

测试 http://127.0.0.1:3289/pop

$ wrk -t12 -c400 -d30s http: //127.0.0.1:3289/pop Running   30s  test @ http: //127.0.0.1:3289/pop   12  threads  and   400  connections   Thread   Stats   Avg   Stdev   Max  +/-  Stdev   Latency   350.37ms   118.99ms   660.41ms   60.94 %   Req / Sec   98.18   35.94   277.00   79.43 %   33694  requests  in   30.10s ,  4.77MB  read   Socket  errors: connect  0 , read  340 , write  0 , timeout  0 Requests /sec:  1119.44 Transfer /sec:  162.23KB 

测试 http://127.0.0.1:3289/get/10

Running   30s  test @ http: //127.0.0.1:3289/get/10   12  threads  and   400  connections   Thread   Stats   Avg   Stdev   Max  +/-  Stdev   Latency   254.90ms   95.43ms   615.14ms   63.51 %   Req / Sec   144.84   61.52   320.00   66.58 %   46538  requests  in   30.10s ,  22.37MB  read   Socket  errors: connect  0 , read  28 , write  0 , timeout  0 Requests /sec:  1546.20 Transfer /sec:  761.02KB 

性能还算不错,再测试一下没有 Redis 操作的 http://127.0.0.1:3289/

$ wrk -t12 -c400 -d30s http: //127.0.0.1:3289/ Running   30s  test @ http: //127.0.0.1:3289/   12  threads  and   400  connections   Thread   Stats   Avg   Stdev   Max  +/-  Stdev   Latency   127.86ms   41.71ms   260.69ms   55.22 %   Req / Sec   258.56   92.25   520.00   68.90 %   92766  requests  in   30.10s ,  13.45MB  read Requests /sec:  3081.87 Transfer /sec:  457.47KB 

Requests/sec: 3081.87

关闭 sanic 日志记录,测试 http://127.0.0.1:3289/

$ wrk -t12 -c400 -d30s http: //127.0.0.1:3289/ Running   30s  test @ http: //127.0.0.1:3289/   12  threads  and   400  connections   Thread   Stats   Avg   Stdev   Max  +/-  Stdev   Latency   34.63ms   12.66ms   96.28ms   58.07 %   Req / Sec   0.96k   137.29   2.21k   73.29 %   342764  requests  in   30.10s ,  49.69MB  read Requests /sec:  11387.89 Transfer /sec:  1.65MB 

Requests/sec: 11387.89

实际代理性能测试

test_proxy.py 用于测试实际代理性能

运行代码

$ cd test $ python test_proxy.py # 可设置的环境变量 TEST_COUNT = os.environ. get ( "TEST_COUNT" )  or   1000 TEST_WEBSITE = os.environ. get ( "TEST_WEBSITE" )  or   "https://httpbin.org/" TEST_PROXIES = os.environ. get ( "TEST_PROXIES" )  or   "http://localhost:3289/get/20" 

实测效果

https://httpbin.org/

测试代理: http: //localhost:3289/get/20 测试网站: https: //httpbin.org/ 测试次数:  1000 成功次数:  1000 失败次数:  0 成功率:  1.0 

https://taobao.com

测试代理: http: //localhost:3289/get/20 测试网站: https: //taobao.com/ 测试次数:  1000 成功次数:  984 失败次数:  16 成功率:  0.984 

https://baidu.com

测试代理: http: //localhost:3289/get/20 测试网站: https: //baidu.com 测试次数:  1000 成功次数:  975 失败次数:  25 成功率:  0.975 

https://zhihu.com

测试代理: http: //localhost:3289/get/20 测试网站: https: //zhihu.com 测试次数:  1000 成功次数:  1000 失败次数:  0 成功率:  1.0 

可以看到其实性能是非常棒的,成功率极高。 wink

实际应用示例

import  random import  requests # 确保已经启动 sanic 服务 # 获取多个然后随机选一个 try :  proxies = requests. get ( "http://localhost:3289/get/20" ).json()  req = requests. get ( "https://example.com" , proxies=random.choice(proxies)) except :   raise # 或者单独弹出一个 try :  proxy = requests. get ( "http://localhost:3289/pop" ).json()  req = requests. get ( "https://example.com" , proxies=proxy) except :   raise 

aiohttp 的坑

整个项目都是基于 aiohttp 这个异步网络库的,在这个项目的文档中,关于代理的介绍是这样的。

划重点:aiohttp supports HTTP/HTTPS proxies

但是,它根本就不支持 https 代理好吧,在它的代码中是这样写的。

划重点:Only http proxies are supported

我的心情可以说是十分复杂的。astonished 不过只有 http 代理效果也不错没什么太大影响,参见上面的测试数据。

参考借鉴项目

  • ProxyPool
  • proxy_pool

License

即可领取源码哦!进群:125240963

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!