python - 如何在 jupyterhub 页面中使用 python-selenium 查找现有的 HTML 元素?

标签 python python-3.x selenium

我在 HTML 页面中有以下构造,我想选择 li元素(使用 python-selenium):

<li class="p-Menu-item p-mod-disabled" data-type="command" data-command="notebook:run-all-below">
    <div class="p-Menu-itemIcon"></div>
    <div class="p-Menu-itemLabel" style="">Run Selected Cell and All Below</div>
    <div class="p-Menu-itemShortcut" style=""></div>
    <div class="p-Menu-itemSubmenuIcon"></div>
</li>
我正在使用以下 xpath:
//li[@data-command='notebook:run-all-below']
但似乎没有找到该元素。
完整的、最小的工作示例代码:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Firefox()
driver.get("https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo")

# Wait for the page to be loaded
xpath = "//button[@title='Save the notebook contents and create checkpoint']"
element = WebDriverWait(driver, 600).until(
    EC.presence_of_element_located((By.XPATH, xpath))
)
time.sleep(10)
print("Page loaded")

# Find and click on menu "Run"
xpath_run = "//div[text()='Run']"
element = WebDriverWait(driver, 60).until(
    EC.element_to_be_clickable((By.XPATH, xpath_run))
)
element.click()
print("Clicked on 'Run'")

# Find and click on menu entry "Run Selected Cell and All Below"
xpath_runall = "//li[@data-command='notebook:run-all-below']"
element = WebDriverWait(driver, 600).until(
    EC.element_to_be_clickable((By.XPATH, xpath_runall))
)
print("Found element 'Run Selected Cell and All Below'")
element.click()
print("Clicked on 'Run Selected Cell and All Below'")

driver.close()
环境:
  • MacOS Mojave (10.14.6)
  • python 3.8.6
  • Selenium 3.8.0
  • 壁虎驱动 0.26.0

  • 附录
    我一直在尝试使用 Firefox“Selenium IDE”插件记录这些步骤,该插件为 python 提供了以下步骤:
    sdriver.get("https://hub.gke2.mybinder.org/user/jupyterlab-jupyterlab-demo-y0bp97e4/lab/tree/demo")
    driver.set_window_size(1650, 916)
    driver.execute_script("window.scrollTo(0,0)")
    driver.find_element(By.CSS_SELECTOR, ".lm-mod-active > .lm-MenuBar-itemLabel").click()
    
    当然,这也行不通。使用该代码行我得到一个错误
    selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .lm-mod-active > .lm-MenuBar-itemLabel
    

    最佳答案

    你离得够近了。事实上,您的整个程序只有一个问题,如下所示:

  • xpath_runall = "//li[@data-command='notebook:run-all-below']"由于第一个匹配的元素是 ,因此不会将带有文本的可见元素唯一标识为 Run Selected Cell 和 All Above隐藏 元素。

  • 其他注意事项
    更多优化:
  • 标识为 xpath = "//button[@title='Save the notebook contents and create checkpoint']" 的元素是 可点击元素。所以而不是 EC 为 presence_of_element_located()您可以使用 element_to_be_clickable()
  • 一旦元素通过 EC 返回为 element_to_be_clickable()您可以调用 click()在同一条线上。
  • 将带有文本的元素标识为 Run Selected Cell 和 All below 将是:
    //li[@data-command='notebook:run-all-below']//div[@class='lm-Menu-itemLabel p-Menu-itemLabel' and text()='Run Selected Cell and All Below']
    
  • 作为application通过 JavaScript 构建您需要使用 ActionChains .

  • 解决方案
    您的优化解决方案将是:
  • 代码块:
    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.action_chains import ActionChains
    
    driver = webdriver.Firefox(executable_path=r'C:\WebDrivers\geckodriver.exe')
    driver.get("https://mybinder.org/v2/gh/jupyterlab/jupyterlab-demo/master?urlpath=lab/tree/demo")
    WebDriverWait(driver, 60).until(EC.element_to_be_clickable((By.XPATH, "//button[@title='Save the notebook contents and create checkpoint']")))
    print("Page loaded")
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[text()='Run']"))).click()
    print("Clicked on Run")
    element = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//li[@data-command='notebook:run-all-below']//div[@class='lm-Menu-itemLabel p-Menu-itemLabel' and text()='Run Selected Cell and All Below']")))
    ActionChains(driver).move_to_element(element).click(element).perform()
    print("Clicked on Run Selected Cell and All Below")
    
  • 控制台输出:
    Page loaded
    Clicked on Run
    Clicked on Run Selected Cell and All Below
    
  • 关于python - 如何在 jupyterhub 页面中使用 python-selenium 查找现有的 HTML 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65233000/

    相关文章:

    python - 多个 Sprite 碰撞检测

    java - 如何在下拉列表中使用 xpath 选定文本

    python - 如何重启 PyQt5 应用程序

    python - 使用 python 库 s3fs 写入 AWS S3 失败并出现 EntityTooLarge

    python - Scikit-learn 交叉验证分数 : too many indices for array

    python - 获取两个不同列表中同一索引处的一对值的出现次数

    python-3.x - 在 AWS lambda 中使用/tmp 目录有多安全?

    python - Python3 字典的问题

    python - 从初始加载时不可见的页面主体中抓取数据

    Selenium Webdriver - 点击隐藏元素