首页 > 解决方案 > 使用 Selenium 收集 Javascript 下拉菜单上的每个选项

问题描述

我正在尝试使用 Selenium 收集此页面所有可能版本(级别、事件和季节的所有组合)的 URL。我已经成功地使用driver.find_elements_by_xpath导航到正确的选项并在保存 URL 之前单击它,但这非常慢,我想知道是否有更好的选择。

href如果不单击实际选项,我似乎没有任何属性可以窃取链接。使用Select类并尝试遍历选项更干净,但我仍然必须Select每次都生成对象 - 尝试这样做:

s = Select(driver.find_element_by_xpath("//label[contains(text(), 'Level')]/../select"))
for option in s.options:
    option.click()

适用于第一个选项,但随后给了我错误stale element reference: element is not attached to the page document。我很难过 - 有没有更好的方法来收集这些链接?下面是我的代码片段:

driver.get("https://athletic.net/TrackAndField/Division/Event.aspx?DivID=89120&Event=1")
for i in range(0, len(driver.find_elements_by_xpath("//label[contains(text(), 'Level')]/../select/option"))):
    driver.find_elements_by_xpath("//label[contains(text(), 'Level')]/../select/option")[i].click()
    for j in range(0, len(driver.find_elements_by_xpath("//optgroup//option[contains(text(), 'Meters')]"))):
        driver.find_elements_by_xpath("//optgroup//option[contains(text(), 'Meters')]")[j].click()
        for k in range(0, len(driver.find_elements_by_xpath("//label[contains(text(), 'Season')]/..//option[contains(text(), 'Indoor')]/../option"))):
            driver.find_elements_by_xpath("//label[contains(text(), 'Season')]/..//option[contains(text(), 'Indoor')]/../option")[k].click()
            for l in range(0, len(driver.find_elements_by_xpath("//label[contains(text(), 'Season')]/..//option[contains(text(), '2018')]/../option"))):
                driver.find_elements_by_xpath("//label[contains(text(), 'Season')]/..//option[contains(text(), '2018')]/../option")[l].click()
                with open("links.txt", 'a+') as f:
                    f.write(driver.current_url + ";")

标签: javascriptpythonpython-3.xseleniumweb-crawler

解决方案


URL 是Location由“DivID”Event标识和由“Event”标识的组合。

因此,您可以使用find_elements_by_xpath(复数)查找options两个下拉列表的所有内容,然后使用列表理解value从每个下拉列表中提取属性option

location_option_list = driver.find_elements_by_xpath("//select[@ng-model='appC.locationDivId']/option")
location_values = [location_option.get_attribute('value') for location_option in location_option_list]

event_option_list = driver.find_elements_by_xpath("//select[@ng-model='appC.params.eventId']//option")
event_values = [event_option.get_attribute('value') for event_option in event_option_list]

urls = ""
for location_value in location_values:
    for event_value in event_values:
        urls += "https://www.athletic.net/TrackAndField/Division/Event.aspx?DivID=%s&Event=%s;" \
                % (location_value, event_value)

上述代码仅适用于“高中”和“中学”级别。您可以轻松修改它以处理“青年俱乐部”和“大学”级别


推荐阅读