使用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 上的学习而没有任何阻塞电话😛