Механизация - Как выполнить или «щелкнуть» Мета-обновлениями в рельсах - PullRequest
5 голосов
/ 15 февраля 2011

У меня небольшая проблема с 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

Ответ:

<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

Ответы [ 2 ]

4 голосов
/ 16 февраля 2011

Внутренне, Механизация использует Nokogiri для обработки анализа HTML в DOM.Вы можете получить документ Nokogiri, чтобы использовать XPath или CSS-аксессоры для поиска по возвращаемой странице.

Вот как получить URL перенаправления только с Nokogiri:

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] разбивается на: Найти первое вхождение (at) средства доступа CSS для тега <meta> с атрибутом 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 не может найти тег, потому что нет <meta http-equiv=\"Refresh\"...>.

EDIT: Механизация имеет встроенный способ обработки мета-обновления, установив:

 agent.follow_meta_refresh = true

Это такжеимеет метод для анализа метатега и возврата содержимого.Из документов:

parse (content, uri)

Разбирает задержку и URL-адрес из атрибута содержимого метатега.Parse требует, чтобы URI текущей страницы выводил URL, когда URL не указан.Если указан блок, проанализированная задержка и URL будут переданы ему для дальнейшей обработки.Возвращает ноль, если задержка и URL не могут быть проанализированы.

# <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
2 голосов
/ 22 февраля 2012

Механизация обрабатывает элементы метаобновления так же, как ссылки без текста. Таким образом, ваш код может быть таким простым:

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