2012-05-24 20 views
2

我正在嘗試編寫一個爬網程序,用於從加載的頁面中檢索所有鏈接,並在某些文件中記錄所有請求和響應頭以及響應正文,如XML或txt。我打開在新的瀏覽器窗口中第一次加載頁面的所有鏈接,所以我不會得到這個錯誤:在緩存中找不到元素 - 可能該頁面在Selenium Ruby Web驅動程序中查找後發生了變化?

Element not found in the cache - perhaps the page has changed since it was looked up 

我想知道什麼可以做的請求,並接收來自各環節響應,然後找到輸入的另一種方法元素和提交按鈕形成所有打開的窗口。 除了打開的窗口在右上角有http://www.testfire.net這樣的常見網站搜索框之外,我可以在一定程度上做到這一點。 我想要做的是我想省略這些常見的框,以便我可以使用i.send_keys "value" webdriver方法填充其他輸入值,並且不會出現此錯誤 錯誤:元素未在緩存中找到 - 可能頁面已更改,因爲它被擡起頭。

從每個打開的窗口中檢測和區分輸入標籤的方法是什麼,以便在大多數網站頁面上出現的常用輸入標籤中不會重複填充值。 我的代碼如下:

require 'rubygems' 
require 'selenium-webdriver' 
require 'timeout' 

class Clicker 
def open_new_window(url) 
    @driver = Selenium::WebDriver.for :firefox 
    @url = @driver.get " http://test.acunetix.com " 
    @link = Array.new(@driver.find_elements(:tag_name, "a")) 
    @windows = Array.new(@driver.window_handles()) 
    @link.each do |a| 
     a = @driver.execute_script("var d=document,a=d.createElement('a');a.target='_blank';a.href=arguments[0];a.innerHTML='.';d.body.appendChild(a);return a", a) 
     a.click 
    end 
    i = @driver.window_handles 
    i[0..i.length].each do |handle| 
     @driver.switch_to().window(handle) 
     puts @driver.current_url() 
     inputs = Array.new(@driver.find_elements(:tag_name, 'input')) 
     forms = Array.new(@driver.find_elements(:tag_name, 'form')) 
     inputs.each do |i| 
      begin 
       i.send_keys "value" 
       puts i.class 
       i.submit 
       rescue Timeout::Error => exc 
        puts "ERROR: #{exc.message}" 
       rescue Errno::ETIMEDOUT => exc 
        puts "ERROR: #{exc.message}" 
       rescue Exception => exc 
        puts "ERROR: #{exc.message}" 
      end 
     end 
     forms.each do |j| 
      begin 
       j.send_keys "value" 
       j.submit 
       rescue Timeout::Error => exc 
        puts "ERROR: #{exc.message}" 
       rescue Errno::ETIMEDOUT => exc 
        puts "ERROR: #{exc.message}" 
       rescue Exception => exc 
        puts "ERROR: #{exc.message}" 
      end 
     end 

    end 
#Switch back to the original window 
    @driver.switch_to().window(i[0]) 
end 
end 
ol = Clicker.new 
url = "" 
ol.open_new_window(url) 

指引,我怎樣才能使用硒的webdriver或使用Ruby的net/httphttp.set_debug_output與響應主體所有requeat和響應頭?

回答

1

硒不是嘗試構建「網絡爬蟲」的最佳選擇之一。有時候它可能太脆弱了,特別是當它遇到意想不到的情況時。 Selenium WebDriver是自動化和測試期望和用戶交互的一個很好的工具。 相反,良好的老式捲曲可能是更好的網頁爬行選項。另外,我很確定有一些紅寶石可以幫助你抓取網頁,只是Google搜索它!

但要回答這個問題,實際如果你使用硒的webdriver:

我工作的濾波算法,在這裏你可以添加你到一個變量數組交互元素的HTML。然後,當你進入下一個窗口/ tab/link時,它會檢查變量數組,如果找到匹配的HTML值,則跳過該元素。

不幸的是,SWD不支持通過API獲取請求頭和響應。常見的解決方法是使用第三方代理來攔截請求。

============

現在,我想解決你的代碼的幾個問題。

我建議在迭代鏈接之前,添加一個@default_current_window = @driver.window_handle。這將允許您在撥打@driver.switch_to.window(@default_current_window)時始終返回到腳本末尾的正確窗口。

在您的@links迭代器中,而不是迭代所有可能顯示的窗口,請使用@driver.switch_to.window(@driver.window_handles.last)。這將切換到最近顯示的新窗口(並且每個鏈接點擊只需要發生一次!)。

你可以做這樣的事情幹起來你的投入和表單代碼:

inputs = [] 
inputs << @driver.find_elements(:tag_name => "input") 
inputs << @driver.find_elements(:tag_name => "form") 
inputs.flatten 
inputs.each do |i| 
    begin 
    i.send_keys "value" 
    i.submit 
    rescue e 
    puts "ERROR: #{e.message}" 
    end 
end 

請注意我怎麼只是添加了所有你想要SWD尋找到您遍歷一個數組變量的元素。然後,當壞事發生,需要一個單一的救援(我假設你不希望從那裏自動退出,這就是爲什麼你只是要打印的消息到屏幕)。

學習乾涸你的代碼,並使用外部的寶石將幫助你實現很多你正在嘗試做的,並以更快的速度。

相關問題