参考资料:python3网络爬虫开发实战
代理池共分为四个模块:‘获取模块’,‘存储模块’,’检测模块‘,(’api‘模块)
- 获取模块:主要通过元类实现,各大代理的抓取
- 存储模块:通过redis有序集合并通过检测模块检测代理是否可用
- 检测模块:通过asyncio和aiohttp实现异步并发请求,从而达到快读检测代理的有效性
- api模块:(个人感觉有点鸡肋了)用flask构建一个本地api接口。每次访问本地接口,api都会从reids里调用可用的代理返回。对于实现高并发请求有点慢。所以直接从redis里获取可用代理会更快些
在代理网站网页结构不更新的情况下代理池可以稳定的获取2000+以上的代理。对于检测不同的网站,代理的有效性数量也不一样。
大部分网站都能够维持1000+以上的代理,对于小规模的数据采集任务已经够用了。
源码:https://github.com/voyagelll/proxyPool
以下是直接通过redis获取代理的代码
import redis
import json
import requests
import random
REDIS_HOST = '127.0.0.1'
REDIS_PORT = 6379
REDIS_KEY = 'proxies'
REDIS_PASSWORD = None
class ProxyMiddleware(object):
def __init__(self):
self.redis = redis.StrictRedis(host=REDIS_HOST, port=REDIS_PORT, password=REDIS_PASSWORD)
def get_random_url(self):
result = self.redis.zrangebyscore(REDIS_KEY, 10, 10)
if len(result):
proxy = random.choice(result)
if isinstance(proxy, bytes):
proxy = proxy.decode('utf-8')
print(proxy)
return proxy
else:
result = self.redis.zrevrange(REDIS_KEY, 0, 10)
if len(result):
if isinstance(proxy, bytes):
proxy = proxy.decode('utf-8')
return proxy
else:
print('proxy pool running out ...')
def process_request(self, request, spider):
if request.meta.get('retry_times'):
proxy = self.get_random_url()
if proxy:
url = 'https://{}'.format(proxy=proxy)
request.meta['proxy'] = uri
if __name__ == '__main__':
proxy = ProxyMiddleware()
proxy.get_random_url()
结果: