2015-09-11 49 views
3

一個頁面加載35.000個元素,其中只有前10個是我感興趣的。返回所有元素使得拼圖非常緩慢。 我只成功無論是在第一個元素返回:如何返回X元素[Selenium]?

driver.find_element_by 

或返回所有,35.000元,有:

driver.find_elements_by 

任何人都知道一個方法來返回找到元素的X金額是多少?

+0

你能給我們一個返回HTML的例子嗎?前10名和其餘的格式是什麼?無論元素是什麼,你只需要前10個元素? – JeffC

回答

2

Selenium不提供允許只返回.find_elements...調用片的功能。一個通用的解決方案,如果你想優化的東西,所以你不需要讓Selenium返回每一個元素,就是在瀏覽器端用JavaScript執行切片操作。我在這裏給出了這個答案。如果你想使用XPath來選擇DOM節點,你可以在這裏修改答案,或者你可以使用我提交的another answer中的方法。

from selenium import webdriver 
driver = webdriver.Chrome() 
driver.get("http://www.example.com") 

# We add 35000 paragraphs with class `test` to the page so that we can 
# later show how to get the first 10 paragraphs of this class. Each 
# paragraph is uniquely numbered. 
driver.execute_script(""" 
var html = []; 
for (var i = 0; i < 35000; ++i) { 
    html.push("<p class='test'>"+ i + "</p>"); 
} 
document.body.innerHTML += html.join(""); 
""") 

elements = driver.execute_script(""" 
return Array.prototype.slice.call(document.querySelectorAll("p.test"), 0, 10); 
""") 

# Verify that we got the first 10 elements by outputting the text they 
# contain to the console. The loop here is for illustration purposes 
# to show that the `elements` array contains what we want. In real 
# code, if I wanted to process the text of the first 10 elements, I'd 
# do what I show next. 
for element in elements: 
    print element.text 

# A better way to get the text of the first 10 elements. This results 
# in 1 round-trip between this script and the browser. The loop above 
# would take 10 round-trips. 
print driver.execute_script(""" 
return Array.prototype.slice.call(document.querySelectorAll("p.test"), 0, 10) 
      .map(function (x) { return x.textContent; });; 
""") 

driver.quit() 

需要的繁瑣程序Array.prototype.slice.call因爲什麼document.querySelectorAll返回看起來像Array但實際上不是一個Array對象。 (這是一個NodeList。)所以它沒有.slice方法,但可以將它傳遞給Arrayslice方法。

1

下面是一個顯着不同的方法作爲不同的答案,因爲有些人會喜歡這一個給我給的other one,或另一個給這個。

這一個依賴於使用XPath切片結果:

from selenium import webdriver 
driver = webdriver.Chrome() 
driver.get("http://www.example.com") 

# We add 35000 paragraphs with class `test` to the page so that we can 
# later show how to get the first 10 paragraphs of this class. Each 
# paragraph is uniquely numbered. These paragraphs are put into 
# individual `div` to make sure they are not siblings of one 
# another. (This prevents offering a naive XPath expression that would 
# work only if they *are* siblings.) 
driver.execute_script(""" 
var html = []; 
for (var i = 0; i < 35000; ++i) { 
    html.push("<div><p class='test'>"+ i + "</p></div>"); 
} 
document.body.innerHTML += html.join(""); 
""") 

elements = driver.find_elements_by_xpath(
    "(//p[@class='test'])[position() < 11]") 
for element in elements: 
    print element.text 

driver.quit() 

請注意,XPath使用基於1的索引,以便< 11確實是正確的表達。圍繞表達式第一部分的括號是絕對必要的。使用這些括號,[position() < 11]測試檢查節點集中每個節點具有的位置,該位置是括號中表達式的結果。沒有它們,位置測試將檢查節點相對於它們的父節點的位置,這將匹配所有節點,因爲所有<p>位於它們各自的<div>中的第一位置。 (這就是爲什麼我添加了上述那些<div>要素:顯示此問題)

,如果我使用XPath我的選擇是已經我會用這個解決方案。否則,如果我正在通過CSS選擇器或id進行搜索,我不會將它轉換爲XPath來執行切片。我會用我展示的另一種方法。

相關問題