Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Selenium在Python中使用Submit循环动态下拉列表_Python_Selenium_Web Scraping - Fatal编程技术网

Selenium在Python中使用Submit循环动态下拉列表

Selenium在Python中使用Submit循环动态下拉列表,python,selenium,web-scraping,Python,Selenium,Web Scraping,我已经花了大约一天半的时间在这个问题上,但我似乎没有取得任何进展。我是Selenium的新手,目前正在尝试从一个动态web应用程序中收集数据,因为没有静态URL,所以BeautifulSoup(我典型的go-to)不是一个选项。我正在抓取的应用程序是一个汽车零件目录,我需要选择第一个可用年份,加载可用品牌,选择第一个品牌,加载可用型号,选择第一个型号,然后单击提交,抓取结果数据,然后返回并执行下一个型号。完成所有模型后,继续下一个make并开始使用更多模型。当所有模型完成后,移到下一年,然后完成

我已经花了大约一天半的时间在这个问题上,但我似乎没有取得任何进展。我是Selenium的新手,目前正在尝试从一个动态web应用程序中收集数据,因为没有静态URL,所以BeautifulSoup(我典型的go-to)不是一个选项。我正在抓取的应用程序是一个汽车零件目录,我需要选择第一个可用年份,加载可用品牌,选择第一个品牌,加载可用型号,选择第一个型号,然后单击提交,抓取结果数据,然后返回并执行下一个型号。完成所有模型后,继续下一个make并开始使用更多模型。当所有模型完成后,移到下一年,然后完成所有可用的模型,然后是模型。我的嵌套for循环如下所示:

from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import StaleElementReferenceException

def make_waitfor_elem_updated_predicate(driver, 
    waitfor_elem_xpath_select):
    elem = driver.find_element_by_xpath(waitfor_elem_xpath_select)

def elem_updated(driver):
    try:
        elem.text
    except StaleElementReferenceException:
        return True
    except:
        pass

    return False

return lambda driver: elem_updated(driver)

class Partbot:

    def __init__(self):
        self.home_page = 'http://monroe-px.rtrk.com/en-US/e-catalog'
        self.driver = webdriver.Chrome()
        self.year_xpath = '//select[@id="widget-ymm-year-desktop"]'
        self.make_xpath = '//select[@id="widget-ymm-make-desktop"]'
        self.model_xpath = '//select[@id="widget-ymm-model-desktop"]'

    def get_select(self, xpath_select):
        select_elem = self.driver.find_element_by_xpath(xpath_select)
        select = Select(select_elem)
        return select

    def select_option(self, xpath_select, value, 
                 waitfor_elem_xpath_select=None):
        if waitfor_elem_xpath_select:
            func = make_waitfor_elem_updated_predicate(
                       self.driver,
                       waitfor_elem_xpath_select
                   )

        select = self.get_select(xpath_select)
        select.select_by_value(value)

        return self.get_select(xpath_select)

    def make_select_option_iterator(self, xpath_select, 
                             waitfor_elem_xpath_select):

        def next_option(xpath_select_select, 
                  waitfor_elem_xpath_select):
            select = self.get_select(xpath_select)
            select_option_values = [
                 '{}'.format(op.get_attribute('value'))
                  for op
                  in select.options[1:]
                  ]
            for v in select_option_values:
                select = self.select_option(xpath_select, v, 
                                   waitfor_elem_xpath_select)
                yield select.first_selected_option.text

        return lambda: next_option(xpath_select, 
                      waitfor_elem_xpath_select)

    def load_page(self):
        self.driver.get(self.home_page)

        def page_loaded(driver):
            path = '//select[@id="widget-ymm-year-desktop"]'
            return driver.find_element_by_xpath(path)

        wait = WebDriverWait(self.driver, 10)
        wait.until(page_loaded)

    def are_extras_present(self):
        extras = self.driver.find_elements_by_xpath("//*
                  [contains(@id, 'widget-ymm-moreinfo')]")
        if len(extras) >= 1:
            return True
        else:
            return False

    def scrape_items(self):
        years = self.make_select_option_iterator(
            self.year_xpath,
            self.make_xpath
        )

        makes = self.make_select_option_iterator(
            self.make_xpath,
            self.model_xpath
        )

        models = self.make_select_option_iterator(
            self.model_xpath,
            None
        )

        self.load_page()

        try:
            for year in years():
                print(year)
                for make in makes():
                    print(2*' ', make)
                    for model in models():
                        print(4*' ', model)
                        subm = 
self.driver.find_element_by_id('lookup-form-desktop')
                      subm.find_element_by_tag_name("button").click()
                      time.sleep(2)


            except:
                self.driver.quit()

    if __name__ == '__main__':
        pb = Partbot()
        pb.scrape_items()

在单击按钮之前设置模型的值等怎么样?为什么是无限循环?也许在你的问题中包含你的助手函数,而循环是我一直在玩的东西,我并不想在代码中发布。我将进行修订。修订内容将与其他类和助手函数一起发布。我尝试在点击按钮之前再次添加值,但随后所有三个循环都退出,程序停止。我不太确定我会错在哪里,但这很令人沮丧。我对硒还不熟悉,所以我可能会在这里抓住救命稻草。感谢您的帮助!快速建议:在关闭驱动程序之前,清除try-catch或打印异常。了解selenium的抱怨可能会有很大帮助。您可以在chrome开发工具的
network
选项卡中检测page发出的请求。如果您模拟这些请求,您可以得到json格式的直接响应。在单击按钮之前设置模型的值等怎么样?为什么是无限循环?也许在你的问题中包含你的助手函数,而循环是我一直在玩的东西,我并不想在代码中发布。我将进行修订。修订内容将与其他类和助手函数一起发布。我尝试在点击按钮之前再次添加值,但随后所有三个循环都退出,程序停止。我不太确定我会错在哪里,但这很令人沮丧。我对硒还不熟悉,所以我可能会在这里抓住救命稻草。感谢您的帮助!快速建议:在关闭驱动程序之前,清除try-catch或打印异常。了解selenium的抱怨可能会有很大帮助。您可以在chrome开发工具的
network
选项卡中检测page发出的请求。如果您模拟这些请求,您可以得到json格式的直接响应。