Python - Selenium - 循环访问下拉菜单 - 选项不可见

时间:2018-05-24 21:31:30

标签: python selenium web-scraping

背景信息:我正试图通过此网页检索有关哥伦比亚2015年市政选举数据的信息:https://elecciones.registraduria.gov.co:81/esc_elec_2015/99AL/DAL01004ZZZZZZZZZZZZ_L1.htm

作为一个起点,我已经使用BeautifulSoup(15.152)成功地在Abejorral市注册了选民(“personas habilitadas”)的数量。下一步是对所有市镇(“municipios”)做同样的事情。

为了做到这一点,我试图在Python 3.5中绕过Selenium循环浏览“Municipio”下拉菜单,这样我就可以逐个选择每个municipio并检索“personas habilitadas”的相应数字。我目前面临的问题是我无法告诉Selenium在下拉菜单中选择另一个选项/市政当局,例如“Abriaqui”。相应的HTML代码在这里(有意缩短的选项列表):

<select id="combo3" class="chosen-select" style="display: none;">
   <option value="../99AL/DAL01ZZZZZZZZZZZZZZZ_L1.htm">Todos</option>
   <option selected="selected" value="../99AL/DAL01004ZZZZZZZZZZZZ_L1.htm">ABEJORRAL</option>
   <option value="../99AL/DAL01007ZZZZZZZZZZZZ_L1.htm">ABRIAQUI</option>
   <option value="../99AL/DAL01010ZZZZZZZZZZZZ_L1.htm">ALEJANDRIA</option>
   <option value="../99AL/DAL01013ZZZZZZZZZZZZ_L1.htm">AMAGA</option>
   <option value="../99AL/DAL01300ZZZZZZZZZZZZ_L1.htm">YONDO-CASABE</option>
   <option value="../99AL/DAL01301ZZZZZZZZZZZZ_L1.htm">ZARAGOZA</option>
</select>

关于SO之前的问题(例如Selenium - Python - drop-down menu option value),我首先尝试了使用Selenium进行下拉菜单的基本方法,即在下面使用其Select方法方式:

#Preamble to code
#Importing packages
import selenium
import time
from selenium import webdriver

url = https://elecciones.registraduria.gov.co:81/esc_elec_2015/99AL/DAL01004ZZZZZZZZZZZZ_L1.htm #Setting URL

driver = webdriver.Chrome()
driver.implicitly_wait(5)
driver.get(url)

time.sleep(20)


from selenium.webdriver.support.ui import Select

select = Select(driver.find_element_by_id('combo3')) #Selecting the drop-down menu by ID
select.select_by_value("../99AL/DAL01007ZZZZZZZZZZZZ_L1.htm") # Trying to select the option in drop-down menu by value. Error arises.

按值选择时出现ElementNotVisibleException错误。所以我尝试了解决SO上提供的其他解决方案的一些故障排除(参见这里:Selecting a value from a drop-down option using selenium python),例如通过XPath查找元素然后单击它。这是我试过的代码:

driver.find_element_by_xpath("//select[@id='combo3']/option[@value='../99AL/DAL01007ZZZZZZZZZZZZ_L1.htm']").click()

再次出现ElementNotVisibleException。接下来,我尝试一下这里建议的内容(ElementNotVisibleException: Message: element not visible - Python3 Selenium),即实现一些等待时间并等待,直到下拉菜单对应的元素变为可点击使用以下代码:

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

element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//select[@id='combo3']")))
element.click()

我在这里得到TimeoutException。我之前使用Chrome的开发人员工具控制台检查了是否有两个或更多元素与定位器匹配且只有一个(长度:1)所以我认为其他可能导致超时但是我无法找到什么它可能是。

通过实现其他方法(如EC.visibility_of_element_located)尝试某些变通方法(例如此处建议的Python selenium drop down menu click)时,我也会收到TimeoutException。以下是引发TimeoutException的代码:

element = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//select[@id='combo3']")))
select = Select(element)

正如你所看到的,我尝试过各种技巧尝试从Municipio下拉菜单中选择一个不同的选项,但仍无法解决这个问题。任何帮助或建议,告诉我我错过或做错了将不胜感激。提前谢谢!

1 个答案:

答案 0 :(得分:0)

ID为'combo3'的select元素的样式为“display:none;”这让它对Selenium不可见。您可以使用div ID'combo3_chosen'来驱动元素,并输入您想要的结果。

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

select_div = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//div[@id='combo3_chosen']")))
select_div.click()
input = WebDriverWait(driver, 10).until(EC.visibility_of_any_elements_located((By.XPATH, "//input")))
input[0].send_keys("Todos")
input[0].send_keys(Keys.RETURN)

在我的示例中,我单击select_div,它会打开一个带有下拉列表的输入。然后我输入'Todos'并按返回加载'Todos'部分。

我使用'visibility_of_any_elements_located'作为输入,因为页面上有多个隐藏的输入(其他选择)。如果我使用'visibility_of_element_located',Selenium会尝试返回不可见的第一个输入。 'visibility_of_any_elements_located'将返回任何可见的输入。

或者,您可以打开select_div并找到所需的结果,然后单击该元素。