【问题标题】:Mechanize - How to follow or "click" Meta refreshes in railsMechanize - 如何在 Rails 中关注或“点击”元刷新
【发布时间】:2011-06-27 13:33:00
【问题描述】:

我对机械化有点麻烦。

当使用 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:nil 的未定义方法“[]”:NilClass

【问题讨论】:

  • 当您提出问题时,包含您正在使用的代码和访问的 URL 的基本示例非常重要。

标签: ruby-on-rails ruby mechanize


【解决方案1】:

Mechanize treats meta refresh elements just like links without text. 因此,您的代码可以像这样简单:

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

【讨论】:

    【解决方案2】:

    在内部,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] 分解为:找到 &lt;meta&gt; 标记的 CSS 访问器的第一个匹配项 (at),其 http-equiv 属性为 refresh。获取该标签的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 找不到标签,因为没有&lt;meta http-equiv=\"Refresh\"...&gt;

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

     agent.follow_meta_refresh = true
    

    它还有一个parse the meta tag 并返回内容的方法。来自文档:

    解析(内容,URI)

    从元标记的内容属性中解析延迟和 url。 Parse 在没有指定 url 时需要当前页面的 uri 来推断一个 url。如果给出一个块,解析的延迟和 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
    

    【讨论】:

    • 感谢您的回答。我现在发布了一些示例代码,因为我收到了一个错误。下次我会记得在开头发布示例代码。
    • @Rails 初学者,我添加了另一个你可能会觉得有趣的编辑。
    • doc.at('meta[http-equiv="refresh"]')添加空检查会更好
    猜你喜欢
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多