2015-02-04 27 views
5
yılında Selenyum ile ben şöyle bir JS oluşturulan web sayfasını ayrıştırma am

özellik değerleri: sınıfından bar-text-label den text kapmak dışındaAyrıştırma HTML5 veriye * Python

from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 


driver = webdriver.Firefox() 
driver.get('https://www.consumerbarometer.com/en/graph-builder/?question=M1&filter=country:singapore,canada,mexico,brazil,argentina,united_states,bulgaria,austria,belgium,croatia,czech_republic,denmark,estonia,finland,france,germany,greece,hungary,italy,ireland,latvia,lithuania,norway,netherlands,poland,portugal,russia,romania,serbia,slovakia,spain,slovenia,sweden,switzerland,ukraine,united_kingdom,australia,china,israel,hong_kong_sar,japan,korea,new_zealand,malaysia,taiwan,turkey,vietnam') 

// wait for svg to appear 
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.TAG_NAME, 'svg'))) 

for text in driver.find_elements_by_class_name('bar-text-label'): 
    print(text.text) 

driver.close() 

Ben de bir HTML5 verilerinden değerleri almak istiyorum -attribute. Örneğin, <rect rx="3" ry="3" width="76%" height="40" transform="translate(0,40)" data-value="76" class="bar"></rect> ve bundan 76'u ayrıştırmak istiyorum.

Bu Selenyum'da yapmak mümkün mü?

hiçbir sucess ile, aşağıda her iki denedik:

for text in driver.find_elements_by_class_name('bar'): 
    print(data_value.text) 

for data in driver.find_elements_by_xpath('//*[contains(@data-value)]/@data-value'): 
    print(data.text) 
+0

Bulunduktan sonra öğe üzerindeki '.get_attribute()' yöntemini kullanmayı denediniz mi? –

cevap

4

sizin gibi öğeler varsa aşağıdaki:

<rect rx="3" ry="3" width="76%" height="40" transform="translate(0,40)" data-value="75" class="bar">bar1</rect> 
<rect rx="3" ry="3" width="76%" height="40" transform="translate(0,40)" data-value="76" class="bar">bar2</rect> 
aşağıdaki gibi

Metin değeri ve özellik değerini alabilirsiniz:

elements = driver.find_elements_by_class_name('bar') 
for element in elements: 
    print element.text 
    print element.get_attribute('data-value') 

Bu yazdırır:

bar1 
75 
bar2 
76 
2

Sen çalıştı söz:

for text in driver.find_elements_by_class_name('bar'): 
    print(data_value.text) 

data_value olarak gören

yerde tanımlanmamış, işe yaramaz. print(text.text)'u yaptıysanız, bar sınıfına sahip her öğenin metnini almalısınız. (Bu, ilk snippet'inizde ne esasen budur.)

Ayrıca bu söz: Selenyum en find_element(s)... fonksiyonları elemanları veya elemanların listelerinde daha başka bir şey döndüremez çünkü

for data in driver.find_elements_by_xpath('//*[contains(@data-value)]/@data-value'): 
    print(data.text) 

Bu çalışamaz. Çalışmayacak bir özellik döndürmek için onu almaya çalışıyorsunuz. XPath genellikle buna izin verir, ancak Selenyum ile XPath kullandığınızda, elementlerden başka bir şey elde edemezsiniz.

Sen neler yapabileceğini Jessamyn Smith suggested ya:

results = driver.execute_script(""" 
    var els = document.getElementsByClassName("bar"); 
    var ret = []; 
    for (var i =0, el; (el = els[i]); ++i) { 
     ret.push([el.textContent, el.attributes["data-value"].value]); 
    } 
    return ret; 
""") 
for r in results: 
    print(r[0], r[1]) 

Bu yazısı ve tarayıcı arasında bir gidiş-dönüş alacaktır. Döngü ve .text ve .get_attribute() kullanımı, yineleme başına 2 gidiş-dönüş gerektirir. JavasScript, sonuç çiftleri listesini oluşturur. Her bir çift, elemanın ilk pozisyonundaki metnini ve ikinci pozisyonda data-value değerini içerir.

+0

Bu çok ilginç. J'yi böyle uygulayabileceğini bilmiyordum. – metersk

+0

İlk başta bilmedim. Yerel olarak her şeyi çalıştırırsanız, bu fark büyük değildir, ancak Sulu Laboratuarlar, Tarayıcı Yığını veya testleri uzaktan çalıştırmak için bir şey kullanıyorsanız, gidiş-dönüşler ** çok fazla ** ekler. Birden çok Selenium çağrısını tek bir 'execute_script' (veya' execute_script_async') çağrısına birleştirerek büyük test takımlarını çalıştırmak için gereken süreyi kısaltdım. – Louis