📜  使用Python在selenium中进行非阻塞等待

📅  最后修改于: 2022-05-13 01:55:27.660000             🧑  作者: Mango

使用Python在selenium中进行非阻塞等待

先决条件:使用Selenium 的浏览器自动化
当我们想要进行网络自动化时,我们需要在执行某些操作之前等待一些 javascript 元素加载。就此而言,通常人们使用

Python3
time.sleep(in_seconds)


Python3
from selenium import webdriver
 
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
options.add_argument("disable-infobars")
 
chrome = webdriver.Chrome(the_path_of_webdriver_which_is_an_exe,
                          chrome_options = options, service_args =['--ignore-ssl-errors = true'])
 
login_uri = 'https://auth.geeksforgeeks.org/'
username = 'something'
password = 'anything'
username_xpath = '//*[@id ="luser"]'
password_xpath = '//*[@id ="password"]'
sign_in_xpath = '//*[@id ="Login"]/button'
 
chrome.get(login_uri)


Python3
# return True if element is visible within 30 seconds, otherwise False
def is_visible(locator, timeout = 30):
    try:
        ui.WebDriverWait(chrome, timeout).until(EC.visibility_of_element_located((By.XPATH, locator)))
        return True
    except TimeoutException:
        return False


Python3
if not is_visible(username_xpath): raise RuntimeError("Something went wrong with the username field :(")
username_field = chrome.find_element_by_xpath(username_xpath)
username_field.send_keys(username)
 
if not is_visible(password_xpath): raise RuntimeError("Something went wrong with the password field :(")
password_field = chrome.find_element_by_xpath(password_xpath)
password_field.send_keys(password)
 
if not is_visible(sign_in_xpath): raise RuntimeError("Something went wrong with the sign in field :(")
sign_in_btn = chrome.find_element_by_xpath(sign_in_xpath)
sign_in_btn.click()


这是一个阻塞调用。
通过阻塞调用,我的意思是,无论发生什么,它都会等待或者更确切地说使程序休眠提到的几秒钟。这不是一个好主意,因为它通过使程序有效地变慢来增加延迟。

可能的解决方案是等到一个元素出现,而不是等待更多。

先决条件:安装Python并安装Selenium以及 Web 驱动程序(.exe 文件)
对于带有Selenium的Python Web 自动化,可以通过以下方式实现:

假设您想通过网络自动化登录 GeeksForGeeks,并在网页上显示用户名和密码元素后立即填写登录凭据,而不是等到整个页面加载完毕。

第1步:
您可以按如下方式配置 webdriver:

Python3

from selenium import webdriver
 
options = webdriver.ChromeOptions()
options.add_argument("--start-maximized")
options.add_argument("disable-infobars")
 
chrome = webdriver.Chrome(the_path_of_webdriver_which_is_an_exe,
                          chrome_options = options, service_args =['--ignore-ssl-errors = true'])
 
login_uri = 'https://auth.geeksforgeeks.org/'
username = 'something'
password = 'anything'
username_xpath = '//*[@id ="luser"]'
password_xpath = '//*[@id ="password"]'
sign_in_xpath = '//*[@id ="Login"]/button'
 
chrome.get(login_uri)

在这里,我使用了 chrome web 驱动程序,它会在没有信息栏的情况下开始最大化(全窗口),即它不会说 chrome 是由自动化代码控制的,并且没有任何麻烦地加载 GFG 的标志页面。

请注意,为了找到这些元素的 xpath,您需要进入开发者模式并检查这些元素。

第2步:

Python3

# return True if element is visible within 30 seconds, otherwise False
def is_visible(locator, timeout = 30):
    try:
        ui.WebDriverWait(chrome, timeout).until(EC.visibility_of_element_located((By.XPATH, locator)))
        return True
    except TimeoutException:
        return False

上面的函数is_visible 是我们打算在这里讨论的非阻塞调用的促进者。
解释:
1) locator – 元素的 xpath
2)超时——直到等待元素出现(因为我们不想永远等待)
3)chrome——我们之前初始化的webdriver对象
4) 它利用 ui 的 inbuild 实用程序使 Web 驱动程序等到元素可见(由 xpath 识别)
5)如果它确实出现在超时内,则返回 True 否则 False

第 3 步:
这就是我们使用该函数的方式:

Python3

if not is_visible(username_xpath): raise RuntimeError("Something went wrong with the username field :(")
username_field = chrome.find_element_by_xpath(username_xpath)
username_field.send_keys(username)
 
if not is_visible(password_xpath): raise RuntimeError("Something went wrong with the password field :(")
password_field = chrome.find_element_by_xpath(password_xpath)
password_field.send_keys(password)
 
if not is_visible(sign_in_xpath): raise RuntimeError("Something went wrong with the sign in field :(")
sign_in_btn = chrome.find_element_by_xpath(sign_in_xpath)
sign_in_btn.click()

这里我们调用 is_visible函数并分别传递用户名、密码和登录按钮的 xpath 并等待元素在超时(这里是 30 秒)内出现。如果不可见,那么我们会引发带有适当消息的 RuntimeError。
如果它出现在 30 秒之前,它会继续并通过 xpath 查找元素(因为现在它在网页上可见,因此此调用不会引发异常错误。

然后我们发送数据并点击登录,您可以享受在 GFG 上的学习而没有任何阻塞电话😛