[英]How do I access the 2nd element with the same xpath in python in selenium
What I mean is that the website I'm using has 2 dropmenus named province with the exact same id, so how do I tell python which dropmenu in particular I wanna select.我的意思是我正在使用的网站有 2 个名为省的下拉菜单,具有完全相同的 id,那么我如何告诉 python 我特别想选择哪个下拉菜单。 Of course this is assuming that the issue is that python always picks the first id it sees当然,这是假设问题在于 python 总是选择它看到的第一个 id
from selenium import webdriver
from selenium.webdriver.support.ui import Select
# There are two dropmenu with the same xpath. first time it works fine
# 2nd time it throws an error about element not interactable
Prov = Select(web.find_element_by_xpath('//*[@id="province"]'))
Prov.select_by_index(2)
def Start():
# once opened it will fill in the confirm your age
Day = Select(web.find_element_by_xpath('//*[@id="bday_day"]'))
Day.select_by_index(2)
Month = Select(web.find_element_by_xpath('//*[@id="bday_month"]'))
Month.select_by_index(4)
Month = Select(web.find_element_by_xpath('//*[@id="bday_year"]'))
Month.select_by_index(24)
Prov = Select(web.find_element_by_xpath('//*[@id="province"]'))
Prov.select_by_index(5)
Button = web.find_element_by_xpath('//*[@id="popup-subscribe"]/button')
Button.click()
# have to go through select your birthday
Start()
# 2 seconds is enough for the website to load
time.sleep(2)
# this throws and error.
Prov = Select(web.find_element_by_xpath('//*[@id="province"]'))
Prov.select_by_index(5)
Selenium has functions硒有功能
find_element_by_...
without s
in word element
to get only first element find_element_by_...
在 word element
没有s
只获取第一个元素find_elements_by_...
with s
in word elements
to get all elements find_elements_by_...
在单词elements
使用s
来获取所有元素Selenium doc: 4. Locating Elements¶ Selenium 文档: 4. 定位元素¶
So you can get all elements as list (even if there is only one element in HTML)因此,您可以将所有元素作为列表(即使 HTML 中只有一个元素)
(if there is no elements then you get empty list) (如果没有元素,那么你会得到空列表)
elements = web.find_elements_by_xpath('//*[@id="province"]')
and later slice it然后切片
first = elements[0]
second = elements[1]
last = elements[-1]
list_first_and_second = elements[:1]
EDIT:编辑:
You can also try to slice directly in xpath like您也可以尝试直接在 xpath 中切片,例如
(it starts counting at one, not zero) (它从一开始计数,而不是零)
'//*[@id="province"][2]'
or maybe或者可能
'(//*[@id="province"])[2]'
but I never used it to confirm if it will work.但我从未用它来确认它是否有效。
BTW:顺便提一句:
All ID
should have unique names - you shouldn't duplicate IDs.所有ID
都应该有唯一的名称 - 您不应该重复 ID。
If you check documentation 4. Locating Elements¶ then you see that there is find_element_by_id
without char s
in word element
- to get first and the only element with some ID - but there is no find_elements_by_id
with char s
in word elements
- to get more then one element with some ID.如果您查看文档4. 定位元素find_element_by_id
然后您会看到在 word element
中有没有 char s
find_element_by_id
- 获取第一个也是唯一具有某些 ID 的元素 - 但没有find_elements_by_id
在 word elements
有 char s
- 以获得更多然后一个元素有一些 ID。
EDIT:编辑:
Minimal working code with example HTML in code代码中带有示例 HTML 的最少工作代码
from selenium import webdriver
from selenium.webdriver.support.ui import Select
html = '''
<select id="province">
<option value="value_A">A</options>
<option value="value_B">B</options>
</select>
<select id="province">
<option value="value_1">1</options>
<option value="value_2">2</options>
</select>
'''
driver = webdriver.Firefox()
driver.get("data:text/html;charset=utf-8," + html)
all_elements = driver.find_elements_by_xpath('//*[@id="province"]')
first = all_elements[0]
second = all_elements[1]
prov1 = Select(first)
prov2 = Select(second)
print('--- first ---')
for item in prov1.options:
print('option:', item.text, item.get_attribute('value'))
for item in prov1.all_selected_options:
print('selected:', item.text, item.get_attribute('value'))
print('--- second ---')
for item in prov2.options:
print('option:', item.text, item.get_attribute('value'))
for item in prov2.all_selected_options:
print('selected:', item.text, item.get_attribute('value'))
EDIT:编辑:
There are two province
.有两个province
。
When you use find_element
in Start
then you get first province
in popup - and you can fill it.当您在Start
使用find_element
,您会在弹出窗口中获得第一个province
- 您可以填写它。 When you click button then it closes this popup but it doesn't remove first province
from HTML - it only hide it.当您单击按钮时,它会关闭此弹出窗口,但不会从 HTML 中删除第一个province
- 它只会隐藏它。
Later when you use find_element
you get again first province
in hidden popup - and this time it is not visible and it can't use it - and this gives error.稍后,当您使用find_element
您将再次在隐藏弹出窗口中获得第一个province
- 这次它不可见且无法使用它 - 这会产生错误。 You have to use second province
like in this example.您必须像在本例中一样使用第二个province
。
from selenium import webdriver
from selenium.webdriver.support.ui import Select
import time
def Start():
# once opened it will fill in the confirm your age
Day = Select(web.find_element_by_xpath('//*[@id="bday_day"]'))
Day.select_by_index(2)
Month = Select(web.find_element_by_xpath('//*[@id="bday_month"]'))
Month.select_by_index(4)
Month = Select(web.find_element_by_xpath('//*[@id="bday_year"]'))
Month.select_by_index(24)
# it uses first `province`
Prov = Select(web.find_element_by_xpath('//*[@id="province"]'))
Prov.select_by_index(5)
Button = web.find_element_by_xpath('//*[@id="popup-subscribe"]/button')
Button.click()
web = webdriver.Firefox()
web.get('https://www.tastyrewards.com/en-ca/contest/fritolaycontest/participate')
# have to go through select your birthday
Start()
# 2 seconds is enough for the website to load
time.sleep(2)
# `find_elements` with `s` - to get second `province`
all_province = web.find_elements_by_xpath('//*[@id="province"]')
second_province = all_province[1]
Prov = Select(second_province)
Prov.select_by_index(5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.