2017-03-27 2 views
2

Was ist der effizienteste Weg, um das gleiche Attribut mehrerer Elemente mit Python, Selen und PhantomJS zu erhalten? Meine Lösung verwendet find_elements_by_css_selector, die alle Elemente findet, die ich brauche, die weniger als eine Sekunde dauert, dann durchlaufe ich die Liste, um das Attribut zu erhalten, das ich benötige. Mein Looping dauert über eine Minute mit etwa 2500 Elementen, was mir sehr auffällt, wenn man alle Elemente mit der Methode find_elements_by_css_selector abbildet. Ist get_attribute Methode wirklich so teuer oder mache ich etwas falsch?Python + Selenium erhalten Attribut der Elemente in der Liste effektiv

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

Sie könnten wenig Beschleunigung erhalten, indem 'Liste comprehension' statt' for' Schleife: 'table = [element.get_attribute ('data-info') für element in driver.find_elements_by_css_selector ("tr [id * = 'bet -']")] ' – Andersson

+1

Attribute sind nicht Teil der Objekteigenschaft und es ist so, als hätten wir 2000 separate Aufrufe von webdriver. und wenn das 60 Sekunden dauert, würde ich sagen, dass es ziemlich schnell ist. –

+0

Haben alle mit Ihrem CSS-Selektor gefundenen Elemente das gewünschte Attribut oder nur einige? Wenn nur einige von ihnen dies tun, können Sie zu Ihrem CSS-Selektor hinzufügen, um sicherzustellen, dass sie alle vor dem Schleifen durchlaufen, z. "tr [id * = 'wette -'] [daten-info]". – JeffC

Antwort

5

Das Problem ist, ist jeder .get_attribute() Selen Befehl ein JSON HTTP wire request und es ist natürlich, führt eine Menge Aufwand.

Es gibt keine direkte Möglichkeit, "Batch Get Attribut" für mehrere Elemente zu tun.

Das nächste, was Sie wahrscheinlich tun können, ist die Attribute über JavaScript zu erhalten, die Ausgabe execute_script(), die ein einzelner JSON HTTP-Befehl ist:

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; 
""") 

Ein Nachteil dieses Ansatzes ist, dass Element Attributabruflogik Dieser Fall basiert nicht auf webdriver API specification - dies kann möglicherweise zu inkonsistenten Ergebnissen führen, wenn Sie sowohl Selenium- als auch Js-basierte Ansätze in Ihrer Codebasis verfolgen.

Einige ähnlichen Themen:

+0

Das war wirklich hilfreich, danke! – Gorionovic

Verwandte Themen