작성
·
859
·
수정됨
0
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
# app 폴더 아래 main.py
@app.post("/collect", response_class=HTMLResponse)
async def collect(request: Request):
brandlist = BrandList()
brands = await brandlist.run()
oy_models = []
for brand in brands:
oy_model = BrandListModel(
code=brand["code"],
brand=brand["brand"],
collection_time=brand["time"],
status=brand["status"],
)
oy_models.append(oy_model)
await mongodb.engine.save_all(oy_models)
return templates.TemplateResponse(
"./index.html",
{"request": request, "title": "수집기", "brands": brands},
)
# app 폴더 아래 spcrper.py
class BrandList:
URL = "https://www.#######.co.kr"
def unit_url(self):
url = f"{self.URL}/store/main/getBrandList.do"
return url
async def fetch(self):
async with aiohttp.ClientSession() as session:
async with session.get(self.unit_url()) as response:
soup = BeautifulSoup(await response.text(), "html.parser")
area_info = soup.select("a[data-ref-onlbrndcd]")
branddics = []
for info in area_info:
code = info["data-ref-onlbrndcd"]
name = info.text
collectiontime = date.today()
item = [i["code"] for i in branddics]
if code in item:
pass
else:
branddic = {
"code": f"{code}",
"brand": f"{name}",
"time": f"{collectiontime}",
"status": "Old",
}
branddics.append(branddic)
await session.close()
return branddics
def run(self):
return asyncio.run(self.fetch())
안녕하세요. 강사님. scraper.py 는 terminal에서 값을 잘 가져오고 있습니다. server.py에서 구동 시, 아래와 같은 error가 나오는데 원인을 찾지 못해서요 ㅠ
RuntimeError: asyncio.run() cannot be called from a running event loop
C:\Users\user\Desktop\Project_Scraper\venv\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py👎 RuntimeWarning: coroutine 'BrandList.fetch' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
코드 리뷰 좀 부탁드리겠습니다.
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
님의 문제는 RuntimeError: asyncio.run() cannot be called from a running event loop
및 RuntimeWarning: coroutine 'BrandList.fetch' was never awaited
가 발생하는 것으로 보입니다. 이는 asyncio
가 이미 실행 중인 이벤트 루프 안에서 asyncio.run()
을 호출하려고 할 때 발생하는 문제입니다. FastAPI와 같은 비동기 프레임워크에서는 이미 이벤트 루프가 실행 중이므로, asyncio.run()
을 직접 사용할 수 없습니다.
코드에서 BrandList.run()
메소드 내에서 asyncio.run(self.fetch())
를 호출하는 부분이 문제의 원인입니다. 대신, 이미 실행 중인 이벤트 루프 내에서 비동기 함수를 호출하려면 해당 함수를 await
키워드와 함께 호출해야 합니다. 그러나 BrandList.run()
메소드는 비동기 함수가 아니므로, 이 메소드 자체를 비동기 함수로 바꿔 await
를 사용할 수 있게 해야 합니다.
수정할 수 있는 방안은 다음과 같습니다:
- BrandList.run()
메소드를 비동기 함수로 변경합니다.
- fetch()
호출 시 await
를 사용합니다.
수정된 BrandList
클래스는 아래와 같이 될 수 있습니다:
class BrandList:
URL = "https://www.#######.co.kr"
def unit_url(self):
url = f"{self.URL}/store/main/getBrandList.do"
return url
async def fetch(self):
async with aiohttp.ClientSession() as session:
async with session.get(self.unit_url()) as response:
soup = BeautifulSoup(await response.text(), "html.parser")
...
await session.close()
return branddics
async def run(self):
return await self.fetch()
그리고 collect
함수 내에서 brandlist.run()
을 호출할 때 await
키워드를 사용해야 합니다.
brands = await brandlist.run()
이렇게 수정하면, 기존에 발생했던 오류를 해결할 수 있을 것입니다.