2017-03-27 383 views
2

使用Python,Selenium和PhantomJS获取多个元素的相同属性的最有效方法是什么?我的解决方案使用了find_elements_by_css_selector,它定位了我需要的所有元素,这需要不到一秒的时间,然后循环访问列表以获取我需要的属性。我的循环占用了大约2500个元素,这对我来说看起来很重要,因为考虑所有元素都使用了find_elements_by_css_selector方法。是get_attribute方法真的很贵或我做错了什么?Python + Selenium有效获取列表中元素的属性

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 
+0

您可以通过使用'名单comprehension',而不是'for'循环很少得到加速:'表= [element.get_attribute( 'data-info')for driver.find_elements_by_css_selector(“tr [id * ='bet - ']”)]' – Andersson

+1

属性不作为对象属性的一部分存在,所以它就像有2000个独立的webdriver调用。如果这需要60秒,我会说它非常快。 –

+0

使用CSS选择器定位的所有元素是否都具有您想要的属性或只有其中一些属性?如果只有其中的一部分,你可以添加到你的CSS选择器,以确保它们都在循环之前完成。 “TR [ID * = '赌注 - '] [数据信息]”。 – JeffC

回答

5

的问题是,每一个.get_attribute()硒命令是JSON HTTP wire request,并且它,当然,引入了大量的开销。

没有直接的方法来为多个元素执行“batch get attribute”。

你大概可以做的最接近的是得到通过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的方法,这可能会导致不一致的结果。

一些相关的话题:

+0

这真的很有帮助,谢谢! – Gorionovic