Mechanize – 如何在rails中关注或“单击”Meta刷新

我对Mechanize有点麻烦。

当使用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 

响应:

      

然后我尝试:

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

但我得到:

 NoMethodError:nil的未定义方法'[]':NilClass

在内部, Mechanize使用Nokogiri来处理将HTML解析为DOM。 您可以访问Nokogiri文档,这样您就可以使用XPath或CSS访问器在返回的页面中进行挖掘。

这是如何仅使用Nokogiri获取重定向URL:

 require 'nokogiri' html = <      foo   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访问器的第一个匹配项( at )具有http-equiv属性refresh标记。 获取该标记的content属性并返回url=后面的字符串。

这是一些典型用途的Mechanize代码。 因为您没有提供示例代码,所以您必须使用此代码:

 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找不到标签,因为没有

编辑:Mechanize有一个内置的方法来处理元刷新,通过设置:

  agent.follow_meta_refresh = true 

它还有一个解析元标记并返回内容的方法。 来自文档:

解析(内容,uri)

从元标记的content属性中解析延迟和url。 当没有指定url时,Parse需要当前页面的uri来推断url。 如果给出了一个块,则解析的延迟和url将被传递给它以进行进一步处理。 如果无法解析延迟和url,则返回nil。

 #  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 

Mechanize将元刷新元素视为没有文本的链接。 因此,您的代码可以像这样简单:

 page = agent.get("http://www.euroads.dk/system/index.php?showpage=login") page.meta_refresh.first.click