检测模块
成功将网站的代理获取下来了,现在就需要一个检测模块 来对所有代理进行多轮检测。代理检测可用,分数就设置为100,代理不可用,分数减1,这样就可以实时改变每个代理的可用情况。如要获取有效代理值需要获取分数高的代理即可 。
由于代理的数量非常多,为了提高代理的检测效率,使用异步请求库aiohttp来进行检测。aiohttp类似javascript中的回调,在请求发出之后,程序可以继续执行去做其他的事情,当响应到达时,程序再去处理这个响应,就会没有阻塞,充分利用时间和资源,大大提高效率。
下面是检测模块的代码
# -*- coding: utf-8 -*-
import asyncio
import aiohttp
import time
try:
from aiohttp import ClientError
except:
from aiohttp import ClientProxyConnectionError as ProxyConnectionError
from db import RedisClient
from setting import *
VALID_STATUS_CODES = [200]
TEST_URL = 'http://www.baidu.com'
BATCH_TEST_SIZE = 100
class Test(object):
def __init__(self):
self.redis = RedisClient()
async def test_single_proxy(self, proxy):
"""
测试单个代理
:param proxy:
:return:None
"""
conn = aiohttp.TCPConnector(verify_ssl=False)
async with aiohttp.ClientSession(connector=conn) as session:
if isinstance(proxy, bytes):
proxy = proxy.decode('utf-8')
real_proxy = 'http://'+proxy
print('正在测试', proxy)
async with session.get(TEST_URL, proxy=real_proxy, timeout=15) as response:
if response.status in VALID_STATUS_CODES:
self.redis.max(proxy)
print('代理可用', proxy)
else:
self.redis.decrease(proxy)
print('请求响应码不可法', proxy)
def run(self):
"""
测试主函数
:return:
"""
print('测试器开始运行')
try:
proxies = self.redis.all()
loop = asyncio.get_event_loop()
# 批量测试
for i in range(0, len(proxies),BATCH_TEST_SIZE):
test_proxis = proxies[i:i+BATCH_TEST_SIZE]
tasks = [self.test_single_proxy(proxy) for proxy in test_proxis]
loop.run_until_complete(asyncio.wait(tasks)
time.sleep(5)
except Exception as e:
print('测试器发送错误', e.args)
浙公网安备 33010602011771号