Python Selenium - 在这种情况下(输入框)捕获元素(Xpath 或 CSS 选择器)的最佳方法? [英] Python Selenium - best way to capture element (Xpath or CSS selector) in this case (an input box)?

查看:14
本文介绍了Python Selenium - 在这种情况下(输入框)捕获元素(Xpath 或 CSS 选择器)的最佳方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 selenium 抓取网站,并且我主要使用 xpath 或 CSS 选择器来抓取元素.但是我注意到这些是动态的(尽管我在网上阅读了 CSS 选择器不应该是)并且我不得不经常重新编写代码.我对此很陌生,并希望帮助弄清楚什么是最好的方法.下面是一个元素的示例,该元素是我试图抓取的输入框,我知道更明确的选择器(如 ID)使用起来更健壮,但在这种情况下我似乎找不到任何标识符.下面的元素 -

<输入大小=1"类型=文本"占位符="class=ng-pristine ng-valid ng-touched"></dpm-input-number-bare>

这不起作用 -

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

这里是更高层——它基本上是一个输入固定汇率的输入框(框旁边的标签)

解决方案

您可以使用以下 XPath 定位元素:

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

我们使用 label 元素作为锚点.获取满足以下条件的 input 元素:其 parent 的第一个 preceding-sibling 有一个 label 子元素其中包含固定利率"一词.

如果需要,添加预期条件(元素可以接收点击).假设您要发送12"在输入框中:

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")

进口:

from selenium.webdriver.common.by import By从 selenium.webdriver.support.ui 导入 WebDriverWait从 selenium.webdriver.support 导入 expected_conditions 作为 EC

编辑:其他 XPath 替代方案:

3 XPath 使用 following-sibling 轴:

//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 使用 preceding-sibling 轴和多个 contains 用于 input 元素:

//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][../preceding-sibling::dpm-input-label[1]/label[.=固定汇率"]]//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(.,固定汇率")]]

4 XPath 使用 preceding 轴:

//input[@class=ng-pristine ng-valid ng-touched"][preceding::label[1][.=Fixed Rate"]]//输入[@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]][.=固定利率"]]//input[contains(@class,"ng-pristine") and contains(@class,"ng-valid") and contains(@class,"ng-touched")][preceding::label[1]][包含(.,固定汇率")]]

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>

解决方案

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")]]

这篇关于Python Selenium - 在这种情况下(输入框)捕获元素(Xpath 或 CSS 选择器)的最佳方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆