Используя OpenUri, как я могу получить содержимое перенаправляющей страницы? - PullRequest
7 голосов
/ 03 мая 2010

Я хочу получить данные с этой страницы:

http://www.canadapost.ca/cpotools/apps/track/personal/findByTrackNumber?trackingNumber=0656887000494793

Но эта страница переходит к:

http://www.canadapost.ca/cpotools/apps/track/personal/findByTrackNumber?execution=eXs1

Итак, когда я использую open из OpenUri, чтобы попытаться получить данные, выдается ошибка RuntimeError, говорящая HTTP redirection loop:

Я не совсем уверен, как получить эти данные после того, как они перенаправят и сгенерируют эту ошибку.

Ответы [ 3 ]

23 голосов
/ 07 мая 2010

Вам нужен такой инструмент, как Механизация . Из его описания:

Библиотека Mechanize используется для автоматизация взаимодействия с сайтами. Механизировать автоматически сохраняет и отправляет куки, следит за перенаправлениями, может перейдите по ссылкам и отправьте формы. форма поля могут быть заполнены и отправлены. Механизация также отслеживает сайты, которые вы посетили как история.

что именно то, что вам нужно. Итак,

sudo gem install mechanize

1012 * тогда *

require 'mechanize'
agent = WWW::Mechanize.new
page = agent.get "http://www.canadapost.ca/cpotools/apps/track/personal/findByTrackNumber trackingNumber=0656887000494793"

page.content # Get the resulting page as a string
page.body # Get the body content of the resulting page as a string
page.search(".somecss") # Search for specific elements by XPath/CSS using nokogiri

и вы готовы к рок-н-роллу.

1 голос
/ 26 сентября 2012

Хотя механизация - замечательный инструмент, я предпочитаю «готовить» свою собственную вещь.

Если вы серьезно относитесь к анализу, вы можете взглянуть на этот код. Он служит для сканирования тысяч сайтов на международном уровне каждый день, и, насколько я исследовал и настроил, не существует более стабильного подхода к этому, который также позволяет в дальнейшем настраивать ваши потребности.

require "open-uri"
require "zlib"
require "nokogiri"
require "sanitize"
require "htmlentities"
require "readability"

def crawl(url_address)
self.errors = Array.new
begin
  begin
    url_address = URI.parse(url_address)
  rescue URI::InvalidURIError
    url_address = URI.decode(url_address)
    url_address = URI.encode(url_address)
    url_address = URI.parse(url_address)
  end
  url_address.normalize!
  stream = ""
  timeout(8) { stream = url_address.open(SHINSO_HEADERS) }
  if stream.size > 0
    url_crawled = URI.parse(stream.base_uri.to_s)
  else
    self.errors << "Server said status 200 OK but document file is zero bytes."
    return
  end
rescue Exception => exception
  self.errors << exception
  return
end
# extract information before html parsing
self.url_posted       = url_address.to_s
self.url_parsed       = url_crawled.to_s
self.url_host         = url_crawled.host
self.status           = stream.status
self.content_type     = stream.content_type
self.content_encoding = stream.content_encoding
self.charset          = stream.charset
if    stream.content_encoding.include?('gzip')
  document = Zlib::GzipReader.new(stream).read
elsif stream.content_encoding.include?('deflate')
  document = Zlib::Deflate.new().deflate(stream).read
#elsif stream.content_encoding.include?('x-gzip') or
#elsif stream.content_encoding.include?('compress')
else
  document = stream.read
end
self.charset_guess = CharGuess.guess(document)
if not self.charset_guess.blank? and (not self.charset_guess.downcase == 'utf-8' or not self.charset_guess.downcase == 'utf8')
  document = Iconv.iconv("UTF-8", self.charset_guess, document).to_s
end
document = Nokogiri::HTML.parse(document,nil,"utf8")
document.xpath('//script').remove
document.xpath('//SCRIPT').remove
for item in document.xpath('//*[translate(@src, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")]')
  item.set_attribute('src',make_absolute_address(item['src']))
end
document = document.to_s.gsub(/<!--(.|\s)*?-->/,'')
self.content = Nokogiri::HTML.parse(document,nil,"utf8")
end
1 голос
/ 03 мая 2010

Кажется, что сайт выполняет некоторую логику перенаправления с сеансами. Если вы не отправите обратно сеансовые куки, которые они отправляют по первому запросу, вы попадете в цикл перенаправления. ИМХО, это дерьмовая реализация с их стороны.

Однако я попытался передать им файлы cookie, но не смог заставить их работать, поэтому не могу быть полностью уверен, что это все, что здесь происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...