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

问题描述 投票:0回答:2

我有两个组合框,我需要从中获取数据。我们称之为'制造商'和'模特'

当您从一个框中选择制造商时,另一个框将填充制造商生成的模型。这可以很好地手动工作,但是当我用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()
python selenium selenium-webdriver
2个回答
1
投票

因此,有些奇怪的事情是Selenium点击不会触发附加到对象的所有DOM事件。它通常是由于,例如,未经优化编写的前端代码而发生的。

但是在这里没有做出任何判断,因为Selenium只能遇到它本不应该遇到的问题。

所以这是一个建议。进入浏览器开发工具>控制台,尝试以下示例。我将在JQuery中编写它,但如果您没有JQuery,请随意将其注入页面,或将代码更改为常规document.getElement代码。

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

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

使用它没有羞辱来点击元素。我尽可能使用Selenium的点击,但无论如何,Selenium的点击与真正的人类点击完全不同,因为鼠标/ user32.dll不用于执行点击。因此,如果它是触发对象上所有事件的唯一方法,那么使用javascript虽然不理想,但并没有错。

最好的情况是事件逻辑以一种不必要的方式连接起来,但我认为这不是一个选项。相反,我会这样做(注意我使用C#for Selenium,所以这是对语法的一般猜测。考虑它有点伪代码)

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

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

首先,找到附加到第一个组合框的所有事件,表面上是触发第二个组合框的填充。您可以使用JQuery执行此操作,如下所示:

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

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

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

如果有多个事件,请为每个事件执行一行。我只需要做一次上面的事件示例。这是最后的手段。在宏观方案中确实没有任何问题,但只要有可能,使用手段触发事物显然是一个更好的选择,尽可能接近真实用户的交互。


0
投票

你尝试过以下方法吗?

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()
© www.soinside.com 2019 - 2024. All rights reserved.