Как получить целевой URL-адрес сокращенного URL-адреса с помощью Ruby?

Как взять этот URL-адрес http://t.co/yjgxz5Y и получить целевой URL-адрес, который http://nickstraffictricks.com/4856_how-to-rank-1-in-google/


person Nick    schedule 03.04.2011    source источник
comment
попробуйте этот гем final_redirect_url.   -  person Indyarocks    schedule 04.05.2017
comment
gem final_redirect_url — это именно то, что вам нужно — настоящий URL, без суеты, без суеты. +1   -  person Bob Walsh    schedule 19.05.2017


Ответы (4)


Я использовал open-uri для этого, потому что это красиво и просто. Он получит страницу, но также будет следовать нескольким переадресациям:

require 'open-uri'

final_uri = ''
open('http://t.co/yjgxz5Y') do |h|
  final_uri = h.base_uri
end
final_uri # => #<URI::HTTP:0x00000100851050 URL:http://nickstraffictricks.com/4856_how-to-rank-1-in-google/>

В документации показан хороший пример использования низкоуровневого Net:: HTTP для обработки перенаправлений.

require 'net/http'
require 'uri'

def fetch(uri_str, limit = 10)
  # You should choose better exception.
  raise ArgumentError, 'HTTP redirect too deep' if limit == 0

  response = Net::HTTP.get_response(URI.parse(uri_str))
  case response
  when Net::HTTPSuccess     then response
  when Net::HTTPRedirection then fetch(response['location'], limit - 1)
  else
    response.error!
  end
end

puts fetch('http://www.ruby-lang.org')

Конечно, все это не работает, если страница не использует перенаправление HTTP. Многие сайты используют мета-перенаправления, которые вы должны обрабатывать, извлекая URL-адрес из мета-тега, но это другой вопрос.

person the Tin Man    schedule 03.04.2011
comment
Спасибо! очень полезно .. выполнение h.base_uri.to_s отобразит URL-адрес назначения. - person k2289; 25.01.2013
comment
Я думаю, вы можете пропустить использование блока и просто вызвать open(url).base_uri - person lulalala; 27.11.2013
comment
Версия Net::HTTP должна быть принятым ответом, потому что она обрабатывает SSL, а также рекурсивные перенаправления (большинство примеров, похоже, обрабатывают только одно или другое). Отличная работа! - person Abe Voelker; 04.04.2015

Для разрешения перенаправлений вы должны использовать запрос HEAD, чтобы избежать загрузки всего тела ответа (представьте, что вы разрешаете URL-адрес аудио- или видеофайла).

Рабочий пример с использованием драгоценного камня Фарадея:

require 'faraday'
require 'faraday_middleware'

def resolve_redirects(url)
    response = fetch_response(url, method: :head)
    if response
        return response.to_hash[:url].to_s
    else
        return nil
    end
end

def fetch_response(url, method: :get)
    conn = Faraday.new do |b|
        b.use FaradayMiddleware::FollowRedirects;
        b.adapter :net_http
    end
    return conn.send method, url
rescue Faraday::Error, Faraday::Error::ConnectionFailed => e
    return nil
end

puts resolve_redirects("http://cre.fm/feed/m4a") # http://feeds.feedburner.com/cre-podcast
person ericteubert    schedule 28.12.2013

Вам нужно будет следовать перенаправлению. Я думаю, это поможет:

http://shadow-file.blogspot.com/2009/03/handling-http-redirection-in-ruby.html

person Spyros    schedule 03.04.2011
comment
Не технически правильно. Вам не нужно следовать перенаправлению, вам просто нужно прочитать заголовок Location, который был отправлен, чтобы вызвать перенаправление, как в ответе Младена Яблановича. - person jemminger; 04.04.2011
comment
Возможно, чтобы перенаправление было перенаправлено. Если базовый код не обрабатывает это автоматически, что он не будет использовать Net::HTTP, то перенаправления также должны выполняться до тех пор, пока вы либо не решите, что перенаправления слишком глубокие, либо они, наконец, не разрешатся на конечном URL-адресе. Конкретная страница, на которую делается ссылка, более запутана, чем пример в документации Net::HTTP. - person the Tin Man; 04.04.2011

person    schedule
comment
Согласно документам, Net::HTTP не выполняет рекурсивные перенаправления, которые необходимы, если перенаправление перенаправляется. Похоже, он справится только с первым. - person the Tin Man; 04.04.2011
comment
Истинный. Вам понадобится петля вокруг этого. Но в любом случае, именно так вы будете следовать перенаправлению в Ruby, и я считаю, что это отвечает на вопрос. - person Mladen Jablanović; 04.04.2011