【问题标题】:Select from dropdown using Selenium and Python使用 Selenium 和 Python 从下拉列表中选择
【发布时间】:2018-07-21 09:54:13
【问题描述】:

借助 SeleniumPython。我想抓取一个有嵌套下拉菜单的网页。我只发布下面的嵌套部分:

<div class="dropDown active" data-dropdown-block="FOOTBALL_COMPSEASON" data-dropdown-default="All Seasons">
    <div class="label" id="dd-FOOTBALL_COMPSEASON">Filter by Season</div> 
    <div class="current" data-dropdown-current="FOOTBALL_COMPSEASON" role="button" tabindex="0" aria-expanded="false" aria-labelledby="dd-FOOTBALL_COMPSEASON" data-listen-keypress="true" data-listen-click="true">
        2018/19
    </div>
    <ul class="dropdownList" data-dropdown-list="FOOTBALL_COMPSEASON" role="listbox" aria-labelledby="dd-FOOTBALL_COMPSEASON" data-listen-keypress="true" data-listen-click="true">
        <li role="option" tabindex="0" data-option-name="All Seasons" data-option-id="-1" data-option-index="-1">
             All Seasons
        </li> 
        <li role="option" tabindex="0" data-option-name="2018/19" data-option-id="210" data-option-index="0">
            2018/19
         </li>
         <li role="option" tabindex="0" data-option-name="2017/18" data-option-id="79" data-option-index="1">
              2017/18
         </li>
         <li role="option" tabindex="0" data-option-name="2016/17" data-option-id="54" data-option-index="2">
             2016/17
         </li>
    </ul>
</div>

这是它的外观截图:

所以,我想让爬虫点击下拉菜单并选择 2017/18。

我第一次尝试这个:

driver.get(_url)
select_element = driver.find_elements_by_class_name("dropdownList")[1]

由于dropdownList类在HTML中被多次使用,而我想要的元素位于第二个位置,即&lt;ul class="dropdownList"....是第二次使用dropdown类,所以我使用[1]来获取第二个孩子。

然后我得到这个错误:

文件“shots_2017_18.py”,第 15 行,在 shot_2017_18 中 select_element = driver.find_elements_by_class_name("dropdownList")1 IndexError: list 索引超出范围

我应该改变什么或做什么,以便爬虫可以从下拉列表中选择 2017/18 项目并可以爬取?

【问题讨论】:

  • 你能点击下拉菜单吗?我看到它不是使用 select 和 span 标签制作的。
  • 我的意思是 python 和 selenium ?
  • 其实这就是我想要做的。但是导致上述错误,并且如果您检查下面的答案,也会产生我在下面发布的错误。

标签: python selenium web-crawler


【解决方案1】:

如果您能够点击下拉菜单,请使用 pythonselenium。然后你可以试试这段代码:

更新:

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


driver   = webdriver.Chrome(executable_path = r'C:/Users/user***/Downloads/chromedriver_win32/chromedriver.exe')
driver.maximize_window()

wait = WebDriverWait(driver,40)

driver.get("https://www.premierleague.com/stats/top/players/goals")  

wait.until(EC.visibility_of_element_located((By.ID, 'dd-FOOTBALL_COMPSEASON')))

time.sleep(5)
drop_down_click = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.current[data-dropdown-current='FOOTBALL_COMPSEASON']")))
drop_down_click.click()

options = driver.find_elements_by_css_selector("ul[data-dropdown-list='FOOTBALL_COMPSEASON'] li")

for option in options:
  if "2017/18" in option.text.strip():
    option.click()  

更新1:

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

driver   = webdriver.Chrome(executable_path = r'C:/Users/user***/Downloads/chromedriver_win32/chromedriver.exe')
driver.maximize_window()

wait = WebDriverWait(driver,40)

driver.get("https://www.premierleague.com/stats/top/players/total_scoring_att")


cookie_button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.btn-primary.cookies-notice-accept")))
ActionChains(driver).move_to_element(cookie_button)
driver.execute_script('arguments[0].click();', cookie_button)
wait.until(EC.visibility_of_element_located((By.ID, 'dd-FOOTBALL_COMPSEASON')))

time.sleep(5)
drop_down_click = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.current[data-dropdown-current='FOOTBALL_COMPSEASON']")))
drop_down_click.click()

options = driver.find_elements_by_css_selector("ul[data-dropdown-list='FOOTBALL_COMPSEASON'] li")

for option in options:
  if "2017/18" in option.text.strip():
    option.click()  

解释

显式等待是您定义的代码,用于等待特定条件发生,然后再继续执行代码。最坏的情况是 Thread.sleep(),它将条件设置为要等待的确切时间段。提供了一些方便的方法来帮助您编写只等待所需时间的代码。 WebDriverWait 与 ExpectedCondition 结合使用是实现此目的的一种方式。

更多关于显式等待,可以找到here

【讨论】:

    【解决方案2】:

    在这种情况下,当您的索引超出范围时,这意味着找到的元素是 None 或只有一个,因为您编写的代码是正确的,我认为您输入了错误的 URL。 但是如果 URL 是正确的,那么您可以使用 XPATH 找到您的适当元素。 试试这个代码:

    select_element = driver.find_element_by_xpath("//li[@data-option-name='2017/18']")
    

    【讨论】:

    • 我收到错误:raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//li[@data-option-name='2017/18']"}
    • 这还不够,但尝试:li_tags = driver.find_elements_by_tag_name("li") for item item in li_tags: if item.text == '2017/18': item.click()跨度>
    猜你喜欢
    • 1970-01-01
    • 2023-02-02
    • 1970-01-01
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 2022-10-13
    相关资源
    最近更新 更多