简体   繁体   English

通过 innerHTML 使用 Python 和 Selenium 定位元素

[英]Locating an element using Python and Selenium via innerHTML

I'm new to Selenium and I'm trying to write my first real script using the package for Python.我是 Selenium 的新手,我正在尝试使用 Python 包编写我的第一个真正的脚本。

I'm using:我在用着:

  • Windows 10视窗 10
  • Python 3.10.5 Python 3.10.5
  • Selenium 4.3.0硒 4.3.0

So far I've been able to do everything I need with different selectors, like ID, name, XPATH etc.到目前为止,我已经能够使用不同的选择器完成我需要的一切,比如 ID、名称、XPATH 等。

However I've stumbled upon an issue where I need to find a specific element by using the innerHTML of it.但是,我偶然发现了一个问题,我需要使用它的 innerHTML 来查找特定元素。

The issue I'm facing is that I need to find an element with the innerHTML-value of "Changed" as seen in the HTML below.我面临的问题是我需要找到一个具有“已更改”的 innerHTML 值的元素,如下面的 HTML 所示。

The first challenge I'm facing is that the element doesn't have a unique ID, name or otherwise to identify it and there's many objects/elements of "dlx-treeview-node".我面临的第一个挑战是该元素没有唯一的 ID、名称或其他方式来识别它,并且有很多“dlx-treeview-node”的对象/元素。 The second challenge is that XPATH won't work because the element changes position depending on where you are on the website (the number of "dlx-treeview-node"-elements change), so if I use XPATH I'll get the wrong element depending on where I am.第二个挑战是 XPATH 不起作用,因为元素会根据您在网站上的位置改变位置(“dlx-treeview-node”元素的数量会发生变化),所以如果我使用 XPATH,我会弄错元素取决于我在哪里。

I can successfully get the name by using the below XPATH, "get_attribute" and printing to console, which is why I know it's innerHTML and not innerText, but as mentioned this will change depending on where I am on the website.我可以通过使用下面的 XPATH、“get_attribute”并打印到控制台成功地获取名称,这就是为什么我知道它是 innerHTML 而不是 innerText,但如上所述,这将根据我在网站上的位置而改变。

I would really appreciate any help I can get to solve this challenge and to learn more about the use of Selenium with Python.我非常感谢我能得到任何帮助来解决这个挑战并了解更多关于在 Python 中使用 Selenium 的信息。

Code trials:代码试验:

select_filter_name = wait.until(EC.element_to_be_clickable((By.XPATH, "/html/body/div/app-root/dlx-select-filter-attribute-dialog/dlx-dialog-window/div/div[2]/div/div/div[5]/div/div/dlx-view-column-selector-component/div[1]/dlx-treeview/div/dlx-treeview-nodes/div/dlx-treeview-nodes/div/dlx-treeview-node[16]/div/div/div/div[2]/div/dlx-text-truncater/div")))
filter_name = select_filter_name.get_attribute("innerHTML")
print(filter_name)

HTML: HTML:

 <dlx-treeview-node _nghost-nrk-c188="" class="ng-star-inserted"> <div _ngcontent-nrk-c188="" dlx-droppable="" dlx-draggable="" dlx-file-drop="" class="d-flex flex-column position-relative dlx-hover on-hover-show-expandable-menu bg-control-active bg-control-hover"> <div _ngcontent-nrk-c188="" class="d-flex flex-row ml-2"> <div _ngcontent-nrk-c188="" class="d-flex flex-row text-nowrap expand-horizontal" style="padding-left: 15px;"> <!----> <div _ngcontent-nrk-c188="" class="d-flex align-self-center ng-star-inserted" style="min-width: 16px; margin-left: 3px;"> <!----> </div> <!----> <div _ngcontent-nrk-c188="" class="d-flex flex-1 flex-no-overflow-x" style="padding: 3.5px 0px;"> <div class="d-flex flex-row justify-content-start flex-no-overflow-x align-items-center expand-horizontal ng-star-inserted"> <!----> <dlx-text-truncater class="overflow-hidden d-flex flex-no-overflow-x ng-star-inserted"> <div class="text-truncate expand-horizontal ng-star-inserted">Changed</div> <!----> <!----> </dlx-text-truncater> <!----> </div> <!----> <!----> <!----> </div> </div> <!----> <!----> </div> </div> <!----> <dlx-attachment-content _ngcontent-nrk-c188=""> <div style="position: fixed; z-index: 10001; left: -10000px; top: -10000px; pointer-events: auto;"> <!----> <!----> </div> </dlx-attachment-content> </dlx-treeview-node>

just run this code on your page and you will get an array of all elements which are a div with the value of Changed只需在您的页面上运行此代码,您将获得一个包含所有元素的数组,这些元素是一个值为Changeddiv

# Define XPath Function (used in the next step)
driver.execute_script("function getXPathOfElement(elt) {var path = "";for (; elt && elt.nodeType == 1; elt = elt.parentNode) { idx = getElementIdx(elt); xname = elt.tagName; if (idx > 1) xname += "[" + idx + "]"; path = "/" + xname + path;} return path;}")

# Get all XPaths for all nodes which are a div with the text of "changed"
xpaths = driver.execute_script("return Array.from(document.querySelectorAll(\"div\")).find(el => el.textContent.includes('Changed')).map((node)=>{ return getXPathOfElement(node)});');

Tips提示

  • check if xpaths length is more than or equal to 1检查xpaths长度是否大于或等于 1
  • index xpaths such as xpaths[0] or do loops to make your changes索引xpaths ,例如xpaths[0]或执行循环以进行更改
  • you will now have an xpath which can be used like a normal selector.您现在将拥有一个可以像普通选择器一样使用的 xpath。

good luck祝你好运

Presuming the innerText of the <div> element as a unique text within the HTML DOM to locate the element with the innerHTML as Changed you can use either of the following xpath based locator strategies :假设<div>元素的innerTextHTML DOM中的唯一文本,以定位带有已更改的 innerHTML 的元素,您可以使用以下任一基于xpath定位器策略

  • Using xpath and text() :使用xpathtext()

     element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[text()='Changed']")))
  • Using xpath and contains() :使用xpathcontains()

     element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[contains(., 'Changed')]")))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM