在 Python 中等待循环永远不会完成



我正在为我尝试一个新事物,在谷歌colab.这种组合需要/强制异步编程。

我有一个上下文管理器,它能够处理名为"登录"的登录和注销。 这很好用!

我试图访问的内部页面有数据集,没有链接,只有div 可以点击。

定位器(我相信)工作正常,与我假设的.element_handles()结合使用时应该返回多个元素。

from playwright.async_api import async_playwright
import asyncio
from IPython.display import Image
import nest_asyncio
nest_asyncio.apply()
# browser is set to webkit in the Login() context manager
...
async def loop_over_datasets(browser=None, page=None):
print("starting")
datasets = page.locator("div.horizontal.clickable")
print("continuing")
datasets = await asyncio.gather(datasets.element_handles())
for ds in datasets:
print(f'inside the loop, ds is {ds}')
print("doesn't get here in tact")
# for each dataset I want to launch a new page where the dataset is clicked but I'll settle for sync programming at this point.
# new_page = await ds.click()
# ds_page = await browser.new_page(new_page)
# ds_page.click()

async def get_all_new_info():
async with Login() as (b,l):
await loop_over_datasets(browser=b,page = l)
asyncio.run(get_all_new_info()) #has to be killed manually or it will run forever.

在行中,datasets = await asyncio.gather(datasets.element_handles())gather()实际上没有await就不起作用,await永远不会返回 这意味着我没有"在循环内..."。

没有await我得到了"ds"变量,但这不是我能做的任何事情。

应该如何使用?

如果没有完整的代码,测试起来有点困难,但想分享一些可能有帮助的东西:

datasets = await asyncio.gather(datasets.element_handles())

据我在 Playwright 文档中看到element_handles()返回<List[ElementHandle]>,您正在尝试将此列表传递给需要可等待对象(协程、任务和期货)asyncio.gather,可能这就是它不起作用的原因,所以我会这样做

datasets = datasets.element_handles()

现在,我假设您希望以异步方式浏览这些数据集。您应该能够将 for 循环的内容放入协程中,并在此基础上创建将由gather执行的任务。

async def process_dataset(ds):
new_page = await ds.click()
ds_page = await browser.new_page(new_page)
ds_page.click()
tasks = []
for ds in datasets:
tasks.append(asyncio.create_task(process_dataset(ds)))

await asyncio.gather(*tasks)

最新更新