How do I take this URL http://t.co/yjgxz5Y and get the destination URL which is http://nickstraffictricks.com/4856_how-to-rank-1-in-google/
Asked
Active
Viewed 4,568 times
14
-
try this gem [final_redirect_url](https://github.com/indyarocks/final_redirect_url). – Indyarocks May 04 '17 at 20:23
-
gem final_redirect_url is exactly what you want --> the real URL, no fuss, no muss. +1 – Bob Walsh May 19 '17 at 16:06
4 Answers
24
require 'net/http'
require 'uri'
Net::HTTP.get_response(URI.parse('http://t.co/yjgxz5Y'))['location']
# => "http://nickstraffictricks.com/4856_how-to-rank-1-in-google/"

Mladen Jablanović
- 43,461
- 10
- 90
- 113
-
2According to the docs, Net::HTTP doesn't do recursive redirects, which is necessary if a redirect gets redirected. This looks like it would only handle the first one. – the Tin Man Apr 03 '11 at 23:17
-
1True. You would need a loop around that. But anyway, this is how you would follow a redirect in Ruby, and I believe that answers the question. – Mladen Jablanović Apr 04 '11 at 06:32
8
I've used open-uri
for this, because it's nice and simple. It will retrieve the page, but will also follow multiple redirects:
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/>
The docs show a nice example for using the lower-level Net::HTTP to handle redirects.
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')
Of course this all breaks down if the page isn't using a HTTP redirect. A lot of sites use meta-redirects, which you have to handle by retrieving the URL from the meta tag, but that's a different question.

the Tin Man
- 158,662
- 42
- 215
- 303
-
Thanks! very helpful.. doing h.base_uri.to_s will render destination url. – k_ssup Jan 24 '13 at 20:06
-
I think you can skip the use of block and just call `open(url).base_uri` – lulalala Nov 27 '13 at 04:14
-
The `Net::HTTP` version should be the accepted answer, because it handles SSL as well as recursive redirects (most examples seem to only handle one or the other). Well done! – Abe Voelker Apr 04 '15 at 03:43
3
For resolving redirects you should use a HEAD
request to avoid downloading the whole response body (imagine resolving a URL to an audio or video file).
Working example using the Faraday gem:
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

ericteubert
- 4,531
- 3
- 31
- 35
1
You would have to follow the redirect. I think that would help :
http://shadow-file.blogspot.com/2009/03/handling-http-redirection-in-ruby.html

Spyros
- 46,820
- 25
- 86
- 129
-
1Not technically correct. You don't need to "follow" the redirect, you merely need to read the Location header that was sent to cause the redirect, as in Mladen Jablanović's answer. – jemminger Apr 03 '11 at 21:15
-
1It's possible to have a redirection be redirected. Unless the underlying code handles that automatically, which it won't using Net::HTTP, then the redirects have to be followed too until you either decide the redirections are too deep, or they finally resolve at the final URL. The particular page linked to is more convoluted than the example in Net::HTTP's docs. – the Tin Man Apr 03 '11 at 23:14