代码之家  ›  专栏  ›  技术社区  ›  Mike C.

Python Selenium从两个组合框中获取数据

  •  0
  • Mike C.  · 技术社区  · 5 年前

    我有两个组合框,需要从中获取数据。让我们称它们为“制造商”和“模型”

    从一个框中选择制造商时,另一个框将填充制造商生产的模型。这可以手动操作,但当我使用Selenium以编程方式选择制造商时,“模型”框不会重新填充。这是密码。

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support.ui import Select
    driver = webdriver.Firefox()
    #Base URL
    driver.get("https://example.com/")
    def scrape():    
        #get manufacturer list
        select1 = driver.find_element_by_name("mnfr")
        makes = [x.text for x in select1.find_elements_by_tag_name("option")]
        print(makes)
        #get models list
        for m in makes:
            select1a = Select(driver.find_element_by_name("makeCodeListPlaceHolder"))           
            select1a.select_by_visible_text(m)        
            select2 = driver.find_element_by_name("models")
            models = [x.text for x in select2.find_elements_by_tag_name("option")]
            print(models)
    scrape()
    
    1 回复  |  直到 5 年前
        1
  •  1
  •   Asyranok    5 年前

    因此,Selenium点击并没有触发连接到对象的所有DOM事件,这有一些奇怪之处。它通常是因为,比方说,前端代码编写得不理想。

    但这里不做任何判断,因为硒可能会遇到它本不应该遇到的问题。

    这里有一个建议。进入浏览器开发工具>控制台,然后尝试以下示例。我将在JQuery中编写这篇文章,但如果您没有JQuery,可以在页面上随意插入它,或者将代码更改为常规文档。获取元素代码。

    $("#FirstComboBoxOption").click();
    

    这会触发所有预期事件吗?第二个组合框是否正确填充?

    用它来点击一个元素是没有退票的。我尽可能使用Selenium的点击,但Selenium的点击与真正的人类点击并不完全相同,比如鼠标/用户32。dll不用于执行单击。因此,如果javascript是触发对象上所有事件的唯一方法,那么使用javascript虽然不理想,但也没有错。

    最好的情况是,事件逻辑以一种不必要的方式连接起来,但我将假设这不是一个选项。相反,我会这样做(注意我用C来表示硒,所以这是对语法的一般猜测。

    browser.execute_script("$('#FirstComboBoxOption').click()");
    

    接下来,我假设这对你不起作用,所以这里是下一个选项。

    首先,查找附加到第一个组合框的所有事件,这些事件表面上触发了第二个组合框的填充。可以使用JQuery这样做:

    var elem = $('#FirstComboBoxOption')[0];
    $._data(elem, "events");
    

    做一点游戏,确保你知道真正的点击会触发什么事件。然后,执行以下操作:

    $('#FirstComboBoxOption').trigger('SomeExpectedEvent');
    

    如果有多个事件,则为每个事件执行一行。我只需要做一次上面的事件示例。这是最后的手段。从总体上看,它并没有什么问题,但只要有可能,它显然是一个更好的选择,可以使用尽可能接近真实用户交互的方式触发事件。

        2
  •  0
  •   supputuri    5 年前

    你试过下面的方法吗?

    from selenium import webdriver
    from selenium.webdriver.common.keys import Keys
    from selenium.webdriver.support.ui import Select
    driver = webdriver.Firefox()
    #Base URL
    driver.get("https://example.com/")
    def scrape():    
        #get manufacturer list
        select1 = driver.find_element_by_name("mnfr")
        makes = select1.find_elements_by_tag_name("option") # get the option elements
        print(makes)
        #get models list
        for m in makes:
            #click on list option
            m.click()
            select2 = driver.find_element_by_name("models")
            models = [x.text for x in select2.find_elements_by_tag_name("option")]
            print(models)
    scrape()