项目地址
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