我试图在10个选项卡上运行下面的函数代码。它运行平稳,但我的目标不是等待页面加载,而是在前面的选项卡加载时切换到其他选项卡,因为加载页面需要很长时间。
下面是处理特定页面的函数:
async def search_dial(i,user):
web.find_element(By.XPATH, 'city_code_box').send_keys(get_citycode(user))
web.find_element(By.XPATH, 'dial_box').send_keys(get_dial(user))
await asyncio.sleep(1)
web.find_element(By.NAME, 'click_button_name').click()
当页面加载(休眠行)并返回到页面时,它应该会屈服于其他代码。但是目前它阻塞在最后一行,等待页面完全加载。
下面是代码(实际上它包括上面的函数,以及与这个问题无关的函数,比如get_citycode
):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
web = webdriver.Chrome('C://Users/user/PycharmProjects/project/chromedriver_win32/chromedriver.exe')
web.maximize_window()
async def main():
task1 = asyncio.create_task(search_dial(0, tabs[0])) #tabs is an array which holds all tabs window handlers
task2 = asyncio.create_task(search_dial(1, tabs[1]))
task3 = asyncio.create_task(search_dial(2, tabs[2]))
task4 = asyncio.create_task(search_dial(3, tabs[3]))
task5 = asyncio.create_task(search_dial(4, tabs[4]))
task6 = asyncio.create_task(search_dial(5, tabs[5]))
task7 = asyncio.create_task(search_dial(6, tabs[6]))
task8 = asyncio.create_task(search_dial(7, tabs[7]))
task9 = asyncio.create_task(search_dial(8, tabs[8]))
task10 = asyncio.create_task(search_dial(9, tabs[9]))
await asyncio.gather(task1,task2,task3,task4,task5,task6,task7,task8,task9,task10)
asyncio.run(main())
如何使页面协同线(search_dial
)在页面加载时生成,然后在加载时返回,而不是阻塞?
发布于 2022-03-16 11:21:28
我认为这里对selenium/chromedriver的工作原理有一个误解。真正的延迟在tabs
列表中,但是您没有向我们展示如何生成它。每个条目都是通过打开一个选项卡并执行类似于web.get(url)
的操作来生成的,这是一个阻塞操作。Asyncio对此无能为力:它是“协作”多任务处理,并要求任务显式地将控制权返回到调度程序(使用await
)。Selenium是不合作的,所以异步不会添加任何东西。
我不知道selenium中有任何合作/非阻塞操作。如果页面需要很长时间才能加载,那么添加一个超时就足够了:通常,需要花费很长时间的是一些不必要的(对刮板之类的)图像,而核心内容已经存在了。但这在很大程度上取决于页面。有人可能会提供一个非阻塞的selenium接口;否则,您唯一的选择是运行多个浏览器,如果希望并行化的话。
例如,有关如何做到这一点的讨论,请参见this question。
顺便指出,您的主要函数可以编写为:
async def main():
tasks = [asyncio.create_task(search_dial(i, tab) for i, tab in enumerate(tabs)]
await asyncio.gather(*tabs)
还不清楚您的search_dial
是否真的想要一个窗口处理程序,并将其命名为user
:如果是这样的话,那么这个变量可能会更好地命名。
https://stackoverflow.com/questions/71495882
复制相似问题