#python-3.x #django #async-await #python-requests
#python-3.x #django #async-await #python-запросы
Вопрос:
Я не могу понять, как работает асинхронность. Я отправляю простые запросы get в Google с помощью прокси-сервера, чтобы проверить правильность прокси-сервера в асинхронном методе. Я получаю сообщение об ошибке:
'''object Response can't be used in 'await' expression'''
Метод получения прокси. Код для получения списка прокси скопирован из учебника:
def get_proxies(self, number_of_proxies=10):
"""Returns max 10 free https proxies by scraping
free-proxy website.
@arg number_of_proxies to be returned"""
try:
if number_of_proxies > 10: number_of_proxies = 10
url = 'https://abc-list.net/'
response = requests.get(url)
response_text = response.text
parser = fromstring(response_text)
proxies = set()
for i in parser.xpath('//tbody/tr'):
if len(proxies) >= number_of_proxies:
break
if i.xpath('.//td[7][contains(text(),"yes")]'):
#Grabbing IP and corresponding PORT
proxy = ":".join([i.xpath('.//td[1]/text()')[0], i.xpath('.//td[2]/text()')[0]])
proxies.add(proxy)
return proxies
except Exception as e:
print('Exception while abc list from url: ', e)
return None
Метод проверки достоверности прокси:
async def is_valid_proxy(self, proxy):
"""Check the validity of a proxy by sending
get request to google using the given proxy."""
try:
response = await requests.get("http://8.8.4.4", proxies={"http": proxy, "https": proxy}, timeout=10)
if await response.status_code == requests.codes.ok:
print('got a valid proxy')
return True
except Exception as e:
print('Invalid proxy. Exception: ', e)
return False
Метод получения действительных прокси:
async def get_valid_proxies(self, number_of_proxies=10):
proxies = self.get_proxies(number_of_proxies)
print(len(proxies), proxies)
valid_proxies = []
valid_proxies = await asyncio.gather(*[proxy for proxy in proxies if await self.is_valid_proxy(proxy)])
return valid_proxies
И вызов вышеуказанного метода:
proxies = asyncio.run(get_valid_proxies())
Теперь лучшим решением для меня будет проверить действительность прокси, def get_proxies(self, number_of_proxies=10):
прежде чем добавлять его в список прокси. Но понятия не имею, как добиться этого асинхронным способом. Поэтому я попытался найти обходной путь, но это тоже не работает. Метод работает без асинхронности, но я вызываю этот метод много раз, и он очень медленный, поэтому хотел бы сделать его асинхронным.
Спасибо
Теперь, после изменения приведенного выше кода с помощью aiohttp, он по-прежнему выдает исключение и не выглядит как асинхронный, поскольку запросы, похоже, отправляются после завершения, так как они очень медленные, как и раньше.
Новый is_valid_proxy:
async with aiohttp.ClientSession() as session:
session.proxies={"http": proxy, "https": proxy}
async with session.get('http://8.8.4.4',
timeout=10) as response:
status_code = await response.status_code
# response = await requests.get("https://www.google.com/", proxies={"http": proxy, "https": proxy}, timeout=10)
# if await response.status_code == requests.codes.ok:
if status_code == requests.codes.ok:
print('got a valid proxy')
return True
except Exception as e:
print('Invalid proxy. Exception: ', e)
return False
Даже не отобразит ошибку или исключение. Вот сообщение:
Invalid proxy. Exception:
Комментарии:
1.запросы не совместимы с асинхронностью. Вам нужно будет использовать библиотеку, такую как httpx или aiohttp, для выполнения асинхронных запросов: python-httpx.org/async docs.aiohttp.org/en/stable
2. Спасибо, что указали мне на это. Мне нужен только response.status_code, а не текст или содержимое из ответа. Я подробнее прочитаю о сеансе aiohttp, чтобы узнать, можно ли их использовать с разными прокси и заголовками. Поскольку я отправляю запрос на один веб-сайт 100 * раз, поэтому хочу использовать запрос с другим заголовком и прокси. И у меня не так много знаний, но в моем сценарии, я думаю, было бы неразумно сохранять сеанс?