2011-02-15 50 views
5

機械化有點麻煩。機械化 - 如何關注或「點擊」導軌中的元刷新

使用Mechanize提交表單時。我來到一個元刷新頁面,沒有鏈接。

我的問題是我如何遵循元刷新?

我試圖讓元刷新,但然後我得到一個套接字錯誤。 示例代碼

require 'mechanize' 
agent = WWW::Mechanize.new 
agent.get("http://euroads.dk") 
form = agent.page.forms.first 
form.username = "username" 
form.password = "password" 
form.submit 
page = agent.get("http://www.euroads.dk/system/index.php?showpage=login") 
agent.page.body 

響應:

<html> 
<head> 
    <META HTTP-EQUIV=\"Refresh\" CONTENT=\"0;URL=index.php?showpage=m_frontpage\"> 
</head> 
</html> 

然後我嘗試:

redirect_url = page.parser.at('META[HTTP-EQUIV=\"Refresh\"]')[ 
    "0;URL=index.php?showpage=m_frontpage\"][/url=(.+)/, 1] 

,但我得到:

 
NoMethodError: Undefined method '[]' for nil:NilClass 
+0

,包括你使用和你所訪問的網址,當你的代碼的一個基本的例子這真的很重要問一個問題。 – 2011-02-16 05:05:39

回答

4

在內部,Mechanize使用Nokogiri來處理將HTML解析爲DOM。您可以在Nokogiri文檔中獲得,以便您可以使用XPath或CSS訪問器在返回的頁面中進行挖掘。

這是如何僅引入nokogiri得到重定向URL:

require 'nokogiri' 

html = <<EOT 
<html> 
    <head> 
    <meta http-equiv="refresh" content="2;url=http://www.example.com/"> 
    </meta> 
    </head> 
    <body> 
    foo 
    </body> 
</html> 
EOT 

doc = Nokogiri::HTML(html) 
redirect_url = doc.at('meta[http-equiv="refresh"]')['content'][/url=(.+)/, 1] 
redirect_url # => "http://www.example.com/" 

doc.at('meta[http-equiv="refresh"]')['content'][/url=(.+)/, 1]分解爲:查找CSS訪問爲<meta>標籤與refreshhttp-equiv屬性的第一次出現(at)。取該標記的content屬性並返回url=後面的字符串。

這是典型使用的一些機械化代碼。因爲你沒有給出示例代碼,你的基礎礦井必須先從這方面的工作:

agent = Mechanize.new 
page = agent.get('http://www.examples.com/') 
redirect_url = page.parser.at('meta[http-equiv="refresh"]')['content'][/url=(.+)/, 1] 
page = agent.get(redirect_url) 

編輯:at('META[HTTP-EQUIV=\"Refresh\"]')

您的代碼具有上述at()。請注意,您正在使用單引號字符串轉義雙引號。這會導致一個反斜槓,然後在字符串中加雙引號,這不是我樣本使用的內容,而且是我爲什麼會得到錯誤的第一個猜測。 Nokogiri找不到標籤,因爲沒有<meta http-equiv=\"Refresh\"...>

編輯:機械化有一個內置的方式通過設置來處理元刷新,:

agent.follow_meta_refresh = true 

它還具有parse the meta tag的方法和返回的內容。從文檔:

解析(內容,URI)

分析從meta標籤的內容屬性的延遲和網址。當沒有指定網址時,Parse需要當前頁面的URI來推斷網址。如果給出了一個塊,解析後的延遲和url將被傳遞給它進行進一步處理。 如果無法解析延遲和url,則返回nil。

# <meta http-equiv="refresh" content="5;url=http://example.com/" /> 
uri = URI.parse('http://current.com/') 

Meta.parse("5;url=http://example.com/", uri) # => ['5', 'http://example.com/'] 
Meta.parse("5;url=", uri)      # => ['5', 'http://current.com/'] 
Meta.parse("5", uri)       # => ['5', 'http://current.com/'] 
Meta.parse("invalid content", uri)   # => nil 
+0

謝謝你的回答。我現在發佈了一些示例代碼,因爲出現錯誤。下次我會記得在開始時發佈示例代碼。 – 2011-02-16 11:57:33