当前位置: 移动技术网 > IT编程>脚本编程>Python > 送你一款Python异步爬虫代理池!超级实用!已开源!

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

2018年06月11日  | 移动技术网IT编程  | 我要评论

快播酒色网,快乐大本营2005年7月,唐山绝恋电视剧

项目地址

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   即可获取源码哦!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网