tester.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import asyncio
  2. import aiohttp
  3. from loguru import logger
  4. from proxypool.schemas import Proxy
  5. from proxypool.storages.redis import RedisClient
  6. from proxypool.setting import TEST_TIMEOUT, TEST_BATCH, TEST_URL, TEST_VALID_STATUS
  7. from aiohttp import ClientProxyConnectionError, ServerDisconnectedError, ClientOSError, ClientHttpProxyError
  8. from asyncio import TimeoutError
  9. EXCEPTIONS = (
  10. ClientProxyConnectionError,
  11. ConnectionRefusedError,
  12. TimeoutError,
  13. ServerDisconnectedError,
  14. ClientOSError,
  15. ClientHttpProxyError
  16. )
  17. class Tester(object):
  18. """
  19. tester for testing proxies in queue
  20. """
  21. def __init__(self):
  22. """
  23. init redis
  24. """
  25. self.redis = RedisClient()
  26. self.loop = asyncio.get_event_loop()
  27. async def test(self, proxy: Proxy):
  28. """
  29. test single proxy
  30. :param proxy: Proxy object
  31. :return:
  32. """
  33. async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session:
  34. try:
  35. logger.debug(f'testing {proxy.string()}')
  36. async with session.get(TEST_URL, proxy=f'http://{proxy.string()}', timeout=TEST_TIMEOUT,
  37. allow_redirects=False) as response:
  38. if response.status in TEST_VALID_STATUS:
  39. self.redis.max(proxy)
  40. logger.debug(f'proxy {proxy.string()} is valid, set max score')
  41. else:
  42. self.redis.decrease(proxy)
  43. logger.debug(f'proxy {proxy.string()} is invalid, decrease score')
  44. except EXCEPTIONS:
  45. self.redis.decrease(proxy)
  46. logger.debug(f'proxy {proxy.string()} is invalid, decrease score')
  47. @logger.catch
  48. def run(self):
  49. """
  50. test main method
  51. :return:
  52. """
  53. # event loop of aiohttp
  54. logger.info('stating tester...')
  55. count = self.redis.count()
  56. logger.debug(f'{count} proxies to test')
  57. for i in range(0, count, TEST_BATCH):
  58. # start end end offset
  59. start, end = i, min(i + TEST_BATCH, count)
  60. logger.debug(f'testing proxies from {start} to {end} indices')
  61. proxies = self.redis.batch(start, end)
  62. tasks = [self.test(proxy) for proxy in proxies]
  63. # run tasks using event loop
  64. self.loop.run_until_complete(asyncio.wait(tasks))
  65. if __name__ == '__main__':
  66. tester = Tester()
  67. tester.run()