Obtener la URL final después de que se redirija curl

110

Necesito obtener la URL final después de una redirección de página, preferiblemente con curl o wget.

Por ejemplo, http://google.com puede redirigir a http://www.google.com .

El contenido es fácil de obtener (por ejemplo curl --max-redirs 10 http://google.com -L), pero solo me interesa la URL final (en el primer caso, http://www.google.com ).

¿Hay alguna forma de hacer esto utilizando solo herramientas integradas de Linux? (solo línea de comando)

tornillo
fuente

Respuestas:

191

curlLa -wopción y la subvariable url_effectivees lo que busca.

Algo como

curl -Ls -o /dev/null -w %{url_effective} http://google.com

Más información

-L Seguir redireccionamientos
-s Modo silencioso. No muestre nada
-o ARCHIVO Escribe la salida en <archivo> en lugar de stdout
-w FORMAT Qué generar después de completar

Más

Es posible que desee agregar -I(es decir, en mayúsculas i) también, lo que hará que el comando no descargue ningún "cuerpo", pero luego también usa el método HEAD, que no es lo que incluía la pregunta y corre el riesgo de cambiar lo que hace el servidor. A veces, los servidores no responden bien a HEAD incluso cuando responden bien a GET.

Daniel Stenberg
fuente
4
debería poder usar "-o / dev / null" si no desea el archivo
Gavin Mogan
1
Esa es una gran opción, ¡nunca pensé que curl pudiera hacer eso! Nunca deja de sorprenderme:-)
Josh
1
Eso es más una característica de shell que curl
user151841
1
@DanielStenberg, de lo -Icontrario, descargará el archivo.
Steven Penny
2
Algunos sitios web también necesitan un agente de usuario falsificado curl -A ...para redirigir a la ubicación esperada.
Ivan Kozik
29

Gracias, eso me ayudó. Hice algunas mejoras y las envolví en un script auxiliar "finalurl":

#!/bin/bash
curl $1 -s -L -I -o /dev/null -w '%{url_effective}'
  • -o salida a /dev/null
  • -I no descargues, solo descubre la URL final
  • -s modo silencioso, sin barras de progreso

Esto hizo posible llamar al comando desde otros scripts como este:

echo `finalurl http://someurl/`
Jan Koriťák
fuente
2
Gracias por esas ideas. Lo reescribí para uso de terminal en mi archivo .bashrc como una función, y no hay necesidad de opciones concisas en ese archivo, así que usé los nombres largos para auto-documentar esto:finalurl() { curl --silent --location --head --output /dev/null --write-out '%{url_effective}' -- "$@"; }
gw0
7

como otra opción:

$ curl -i http://google.com
HTTP/1.1 301 Moved Permanently
Location: http://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Sat, 19 Jun 2010 04:15:10 GMT
Expires: Mon, 19 Jul 2010 04:15:10 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 219
X-XSS-Protection: 1; mode=block

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

Pero no pasa del primero.

Gavin Mogan
fuente
6

Puede hacer esto con wget normalmente. wget --content-disposition"url" además, si agrega -O /dev/null, no guardará realmente el archivo.

wget -O /dev/null --content-disposition example.com

Ceagle
fuente
Reemplazar -O /dev/nullsolo de a -O-. Mejor:wget -O- --content-disposition example.com
Maxwel Leite
1
wget -O / dev / null --content-disposition example.com y wget -O- / dev / null --content-disposition example.com producen muchos más resultados que la URL redirigida. curl $ 1 -s -L -I -o / dev / null -w '% {url_effective}' funciona bien para mí.
Eric Klien
5

Gracias. Terminé implementando tus sugerencias: curl -i + grep

curl -i http://google.com -L | egrep -A 10 '301 Moved Permanently|302 Found' | grep 'Location' | awk -F': ' '{print $2}' | tail -1

Devuelve en blanco si el sitio web no redirecciona, pero eso es lo suficientemente bueno para mí, ya que funciona en redirecciones consecutivas.

Podría tener errores, pero de un vistazo funciona bien.

tornillo
fuente
2

Esto funcionaría:

 curl -I somesite.com | perl -n -e '/^Location: (.*)$/ && print "$1\n"'
Mike Q
fuente
2

Los parámetros -L (--location)y -I (--head)todavía haciendo una solicitud HEAD innecesaria a la URL de ubicación.

Si está seguro de que no tendrá más de una redirección, es mejor deshabilitar la ubicación de seguimiento y usar una variable curl% {redirect_url}.

Este código solo realiza una solicitud HEAD a la URL especificada y toma redirect_url de location-header:

curl --head --silent --write-out "%{redirect_url}\n" --output /dev/null "https://""goo.gl/QeJeQ4"

Prueba de velocidad

all_videos_link.txt - 50 enlaces de goo.gl + bit.ly que redirigen a youtube

1. Con seguir ubicación

time while read -r line; do
    curl -kIsL -w "%{url_effective}\n" -o /dev/null  $line
done < all_videos_link.txt

Resultados:

real    1m40.832s
user    0m9.266s
sys     0m15.375s

2. Sin ubicación de seguimiento

time while read -r line; do
    curl -kIs -w "%{redirect_url}\n" -o /dev/null  $line
done < all_videos_link.txt

Resultados:

real    0m51.037s
user    0m5.297s
sys     0m8.094s
Geografia
fuente
Parece bastante poco común saber de antemano que solo habría una redirección ...
SamB
1

No estoy seguro de cómo hacerlo con curl, pero libwww-perl instala el alias GET.

$ GET -S -d -e http://google.com
GET http://google.com --> 301 Moved Permanently
GET http://www.google.com/ --> 302 Found
GET http://www.google.ca/ --> 200 OK
Cache-Control: private, max-age=0
Connection: close
Date: Sat, 19 Jun 2010 04:11:01 GMT
Server: gws
Content-Type: text/html; charset=ISO-8859-1
Expires: -1
Client-Date: Sat, 19 Jun 2010 04:11:01 GMT
Client-Peer: 74.125.155.105:80
Client-Response-Num: 1
Set-Cookie: PREF=ID=a1925ca9f8af11b9:TM=1276920661:LM=1276920661:S=ULFrHqOiFDDzDVFB; expires=Mon, 18-Jun-2012 04:11:01 GMT; path=/; domain=.google.ca
Title: Google
X-XSS-Protection: 1; mode=block
Gavin Mogan
fuente
0

¿Puedes intentarlo?

#!/bin/bash 
LOCATION=`curl -I 'http://your-domain.com/url/redirect?r=something&a=values-VALUES_FILES&e=zip' | perl -n -e '/^Location: (.*)$/ && print "$1\n"'` 
echo "$LOCATION"

Nota: cuando ejecuta el comando curl -I http://your-domain.com tengo que usar comillas simples en el comando como curl -I 'http://your-domain.com'

lakshmikandan
fuente
-3

Podrías usar grep. ¿No te dice a dónde se redirecciona también? Simplemente elimine eso.

Empalme
fuente