Python Selenium - best way to capture element (Xpath or CSS selector) in this case (an input box)?

為{幸葍}努か 提交于 2021-01-28 19:50:57

问题


I am trying to scrape a website with selenium and I am using mostly xpath or CSS selector to grab elements. However I am noticing that these are dynamic (even though I read online that CSS selector shouldnt be) and I am having to re write the code often. I am fairly new to this and would like help figuring out what would be the best way to do this. Below is an example of an element that is an input box that I am trying to grab, I understand more definitive selectors like ID are more robust to use but I cant seem to find any identifiers in this case. Element below -

<dpm-input-number-bare><input size="1" type="text" placeholder="" class="ng-pristine ng-valid ng-touched"></dpm-input-number-bare>

This doesnt work -

driver.find_element_by_css_selector("ng-valid.ng-dirty.ng-touched")

Here is the higher level - its basically an input box to enter the fixed rate (the label right next to the box)

<div class="dpm-form-row"><dpm-input-number class="flex-6"><dpm-input-label><label>Fixed Rate</label></dpm-input-label><dpm-input-number-bare><input size="1" type="text" placeholder="" class="ng-pristine ng-valid ng-touched"></dpm-input-number-bare></dpm-input-number><div class="flex-6"></div></div>

回答1:


You can locate the element with the following XPath :

driver.find_element_by_xpath('//input[@class="ng-pristine ng-valid ng-touched"][../preceding-sibling::dpm-input-label[1]/label[.="Fixed Rate"]]')

We use the label element as an anchor point. Get the input element which fulfill the following condition : the first preceding-sibling of its parent has a label child which contains the term "Fixed Rate".

If needed, add an expected condition (element can receive the click). Assuming you want to send "12" in the input box :

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, '//input[@class="ng-pristine ng-valid ng-touched"][../preceding-sibling::dpm-input-label[1]/label[.="Fixed Rate"]]'))).send_keys("12")

Imports :

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

EDIT : Other XPath alternatives :

3 XPath using following-sibling axis :

//dpm-input-label[label[.="Fixed Rate"]]/following-sibling::dpm-input-number-bare[1]/input
//dpm-input-label[label[contains(.,"Fixed Rate")]]/following-sibling::dpm-input-number-bare[1]/input
//dpm-input-label[contains(.,"Fixed Rate")]/following-sibling::dpm-input-number-bare[1]/input

3 XPath using preceding-sibling axis and multiple contains for the input element :

//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][../preceding-sibling::dpm-input-label[1]/label[.="Fixed Rate"]]
//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][../preceding-sibling::dpm-input-label[1]/label[contains(.,"Fixed Rate")]]
//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][../preceding-sibling::dpm-input-label[1][contains(.,"Fixed Rate")]]

4 XPath using preceding axis :

//input[@class="ng-pristine ng-valid ng-touched"][preceding::label[1][.="Fixed Rate"]]
//input[@class="ng-pristine ng-valid ng-touched"][preceding::label[1][contains(.,"Fixed Rate")]]
//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][preceding::label[1][.="Fixed Rate"]]
//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][preceding::label[1][contains(.,"Fixed Rate")]]



回答2:


Have you tried this?

driver.find_element_by_xpath('//input[@type="text"]')

However, if there are more than one elements by the same XPath, it might raise an error.




回答3:


how about finding the element using its class

driver.find_element_by_class_name('ng-pristine ng-valid ng-touched')



回答4:


Try following approach with xpath:

driver.find_element_by_xpath("//div[@class='dpm-form-row' and contains(., 'Fixed Rate')]//input[@class='ng-pristine ng-valid ng-touched']")


来源:https://stackoverflow.com/questions/63062499/python-selenium-best-way-to-capture-element-xpath-or-css-selector-in-this-ca

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!