tester.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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, TEST_ANONYMOUS, \
  7. TEST_DONT_SET_MAX_SCORE
  8. from aiohttp import ClientProxyConnectionError, ServerDisconnectedError, ClientOSError, ClientHttpProxyError
  9. from asyncio import TimeoutError
  10. EXCEPTIONS = (
  11. ClientProxyConnectionError,
  12. ConnectionRefusedError,
  13. TimeoutError,
  14. ServerDisconnectedError,
  15. ClientOSError,
  16. ClientHttpProxyError,
  17. AssertionError
  18. )
  19. class Tester(object):
  20. """
  21. tester for testing proxies in queue
  22. """
  23. def __init__(self):
  24. """
  25. init redis
  26. """
  27. self.redis = RedisClient()
  28. self.loop = asyncio.get_event_loop()
  29. async def test(self, proxy: Proxy):
  30. """
  31. test single proxy
  32. :param proxy: Proxy object
  33. :return:
  34. """
  35. async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=False)) as session:
  36. try:
  37. logger.debug(f'testing {proxy.string()}')
  38. # if TEST_ANONYMOUS is True, make sure that
  39. # the proxy has the effect of hiding the real IP
  40. if TEST_ANONYMOUS:
  41. url = 'https://httpbin.org/ip'
  42. async with session.get(url, timeout=TEST_TIMEOUT) as response:
  43. resp_json = await response.json()
  44. origin_ip = resp_json['origin']
  45. async with session.get(url, proxy=f'http://{proxy.string()}', timeout=TEST_TIMEOUT) as response:
  46. resp_json = await response.json()
  47. anonymous_ip = resp_json['origin']
  48. assert origin_ip != anonymous_ip
  49. assert proxy.host == anonymous_ip
  50. async with session.get(TEST_URL, proxy=f'http://{proxy.string()}', timeout=TEST_TIMEOUT,
  51. allow_redirects=False) as response:
  52. if response.status in TEST_VALID_STATUS:
  53. if TEST_DONT_SET_MAX_SCORE:
  54. logger.debug(f'proxy {proxy.string()} is valid, remain current score')
  55. else:
  56. self.redis.max(proxy)
  57. logger.debug(f'proxy {proxy.string()} is valid, set max score')
  58. else:
  59. self.redis.decrease(proxy)
  60. logger.debug(f'proxy {proxy.string()} is invalid, decrease score')
  61. except EXCEPTIONS:
  62. self.redis.decrease(proxy)
  63. logger.debug(f'proxy {proxy.string()} is invalid, decrease score')
  64. @logger.catch
  65. def run(self):
  66. """
  67. test main method
  68. :return:
  69. """
  70. # event loop of aiohttp
  71. logger.info('stating tester...')
  72. count = self.redis.count()
  73. logger.debug(f'{count} proxies to test')
  74. cursor = 0
  75. while True:
  76. logger.debug(f'testing proxies use cursor {cursor}, count {TEST_BATCH}')
  77. cursor, proxies = self.redis.batch(cursor, count=TEST_BATCH)
  78. if proxies:
  79. tasks = [self.loop.create_task(self.test(proxy)) for proxy in proxies]
  80. self.loop.run_until_complete(asyncio.wait(tasks))
  81. if not cursor:
  82. break
  83. def run_tester():
  84. host = '96.113.165.182'
  85. port = '3128'
  86. tasks = [tester.test(Proxy(host=host, port=port))]
  87. tester.loop.run_until_complete(asyncio.wait(tasks))
  88. if __name__ == '__main__':
  89. tester = Tester()
  90. tester.run()
  91. # run_tester()