web-dev-qa-db-fra.com

TypeError: Un asyncio.Future, une coroutine ou un awaitable est requis

J'essaie de faire un grattoir Web asynchrone en utilisant beautifulsoup et aiohttp. C'est mon code initial pour démarrer les choses. comprendre ce qui ne va pas avec mon code. Je suis nouveau sur python et j'apprécierais toute aide à ce sujet.

import bs4
import asyncio
import aiohttp


async def parse(page):
    soup=bs4.BeautifulSoup(page,'html.parser')
    soup.prettify()
    print(soup.title)



async def request():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://google.com") as resp:
            await parse(resp)



loop=asyncio.get_event_loop()
loop.run_until_complete(request)

Traceback: -

Traceback (most recent call last):
  File "C:\Users\User\Desktop\Bot\aio-req\parser.py", line 21, in <module>
    loop.run_until_complete(request)
  File "C:\Users\User\AppData\Local\Programs\Python\Python38-32\lib\asyncio\base_events.py", line 591, in run_until_complete
    future = tasks.ensure_future(future, loop=self)
  File "C:\Users\User\AppData\Local\Programs\Python\Python38-32\lib\asyncio\tasks.py", line 673, in ensure_future
    raise TypeError('An asyncio.Future, a coroutine or an awaitable is '
TypeError: An asyncio.Future, a coroutine or an awaitable is required
2
user7657046

Un problème est que loop.run_until_complete(request) devrait être loop.run_until_complete(request()) - Vous devez en fait l'appeler pour qu'il renvoie une coroutine.

Il y a d'autres problèmes - comme si vous passez un objet aiohttp.ClientResponse À parse et que vous le traitez comme du texte/html. Je l'ai fait fonctionner avec ce qui suit mais je ne sais pas si cela répond à vos besoins car parse n'est plus une coroutine.

def parse(page):
    soup=bs4.BeautifulSoup(page,'html.parser')
    soup.prettify()
    return soup.title

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def request():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, "https://google.com")
        print(parse(html))

if __name__ == '__main__':
    loop=asyncio.get_event_loop()
    loop.run_until_complete(request())

Cela fonctionne également:

def parse(page):
    soup=bs4.BeautifulSoup(page,'html.parser')
    soup.prettify()
    print(soup.title)

async def request():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://google.com") as resp:
            parse(await resp.text())

Et enfin, votre code d'origine, en passant un objet de réponse en attente à parse puis en attendant page.text().

async def parse(page):
    soup=bs4.BeautifulSoup(await page.text(),'html.parser')
    soup.prettify()
    print(soup.title)

async def request():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://google.com") as resp:
            await parse(resp)
4
wwii

J'ai changé mon code et cela fonctionne maintenant.

import bs4
import asyncio
import aiohttp


async def parse(page):
    soup=bs4.BeautifulSoup(page,'html.parser')
    soup.prettify()
    print(soup.title)



async def request():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://google.com") as resp:
            html=await resp.text()
            await parse(html)



loop=asyncio.get_event_loop()
loop.run_until_complete(request())
1
user7657046