Django: не удается выполнить асинхронные запросы. зайдите в Google. Ответ на исключение не может быть использован в выражении ‘await’

#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 * раз, поэтому хочу использовать запрос с другим заголовком и прокси. И у меня не так много знаний, но в моем сценарии, я думаю, было бы неразумно сохранять сеанс?