【问题标题】:Python + Selenium get attribute of elements in the list effectivelyPython + Selenium 有效获取列表中元素的属性
【发布时间】:2017-03-27 13:19:03
【问题描述】:

使用 Python、Selenium 和 PhantomJS 获取多个元素的相同属性的最有效方法是什么?我的解决方案使用find_elements_by_css_selector 来定位我需要的所有元素,这需要不到一秒钟的时间,然后我遍历列表以获取我需要的属性。我的循环大约需要 2500 个元素,这对我来说似乎很多,考虑到所有元素都使用 find_elements_by_css_selector 方法映射。 get_attribute 方法真的那么贵还是我做错了什么?

from selenium import webdriver

driver = webdriver.PhantomJS(executable_path=r'mypath\phantomjs.exe')
driver.set_window_size(1120, 550)
driver.get("https://www.something.com")

table = []
elements = driver.find_elements_by_css_selector("tr[id*='bet-']") # takes under 1 second

for element in elements:
   table.append(element.get_attribute('data-info')) # takes over 60 seconds (2000 elements)

driver.close

【问题讨论】:

  • 使用list comprehension 而不是for 循环可能会加速:table = [element.get_attribute('data-info') for element in driver.find_elements_by_css_selector("tr[id*='bet-']")]
  • 属性不作为对象属性的一部分存在,因此就像对 webdriver 进行 2000 次单独调用一样。如果这需要 60 秒,我会说它非常快。
  • 您的 CSS 选择器中的所有元素是否都具有您想要的属性,还是只有其中一些?如果只有其中一些这样做,您可以添加到您的 CSS 选择器以确保所有这些都在循环之前执行,例如“tr[id*='bet-'][数据信息]”。

标签: python selenium selenium-webdriver phantomjs


【解决方案1】:

问题是,每个.get_attribute() selenium 命令都是JSON HTTP wire request,当然,它会引入很多开销。

没有直接的方法可以对多个元素进行“批量获取属性”。

您可能做的最接近的事情是通过 JavaScript 获取属性,发出 execute_script(),这是一个单一的 JSON HTTP 命令:

attributes = driver.execute_script("""
    var result = []; 
    var all = document.querySelectorAll("tr[id*='bet-']"); 
    for (var i=0, max=all.length; i < max; i++) { 
        result.push(all[i].getAttribute('data-info')); 
    } 
    return result;
""")

这种方法的一个缺点是在这种情况下元素属性检索逻辑不是基于webdriver API specification - 如果您在代码库中同时遵循基于 selenium 和基于 js 的方法,这可能会导致结果不一致。

一些相关的话题:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-22
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多