Obtenir l'URL finale après la redirection de curl

111

J'ai besoin d'obtenir l'URL finale après une redirection de page de préférence avec curl ou wget.

Par exemple, http://google.com peut rediriger vers http://www.google.com .

Le contenu est facile à obtenir (ex. curl --max-redirs 10 http://google.com -L), Mais je ne suis intéressé que par l'URL finale (dans le premier cas http://www.google.com ).

Existe-t-il un moyen de le faire en utilisant uniquement les outils intégrés de Linux? (ligne de commande uniquement)

vice
la source

Réponses:

192

curlL' -woption de et la sous-variable url_effectiveest ce que vous recherchez.

Quelque chose comme

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

Plus d'informations

-L Suivre les redirections
-s Mode silencieux. Ne rien afficher
-o FILE Ecrit la sortie dans <file> au lieu de stdout
-w FORMAT Quoi afficher après la fin

Plus

Vous voudrez peut-être également ajouter -I(c'est-à-dire une majuscule i), ce qui fera que la commande ne téléchargera aucun "corps", mais elle utilise également la méthode HEAD, qui n'est pas ce que la question a inclus et risque de changer ce que fait le serveur. Parfois, les serveurs ne répondent pas bien à HEAD même s'ils répondent bien à GET.

Daniel Stenberg
la source
4
vous devriez pouvoir utiliser "-o / dev / null" si vous ne voulez pas le fichier
Gavin Mogan
1
C'est une excellente option, je ne savais pas que curl pouvait faire ça! Ça ne cesse de m'étonner:-)
Josh
1
C'est plus une fonctionnalité de shell que curl
user151841
1
@DanielStenberg dont vous avez besoin, -Isinon il téléchargera le fichier.
Steven Penny
2
Certains sites Web ont également besoin d'un agent utilisateur usurpé curl -A ...pour rediriger vers l'emplacement attendu.
Ivan Kozik
30

Merci, cela m'a aidé. J'ai apporté quelques améliorations et j'ai intégré cela dans un script d'aide "finalurl":

#!/bin/bash
curl $1 -s -L -I -o /dev/null -w '%{url_effective}'
  • -o sortie vers /dev/null
  • -I ne téléchargez pas réellement, découvrez simplement l'URL finale
  • -s mode silencieux, pas de barre de progression

Cela a permis d'appeler la commande à partir d'autres scripts comme celui-ci:

echo `finalurl http://someurl/`
Jan Koriťák
la source
2
Merci pour ces idées. Je l'ai réécrit pour l'utilisation du terminal dans mon fichier .bashrc en tant que fonction, et il n'y a pas besoin des options laconiques dans ce fichier, j'ai donc utilisé les noms longs pour auto-documenter ceci:finalurl() { curl --silent --location --head --output /dev/null --write-out '%{url_effective}' -- "$@"; }
gw0
7

comme autre option:

$ 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>

Mais cela ne dépasse pas le premier.

Gavin Mogan
la source
6

Vous pouvez généralement le faire avec wget. wget --content-disposition"url" en plus si vous ajoutez, -O /dev/nullvous ne sauvegarderez pas réellement le fichier.

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

Ceagle
la source
Remplacez -O /dev/nulluniquement de à -O-. Mieux:wget -O- --content-disposition example.com
Maxwel Leite
1
wget -O / dev / null --content-disposition example.com et wget -O- / dev / null --content-disposition example.com produisent beaucoup plus de sortie que l'URL redirigée. curl $ 1 -s -L -I -o / dev / null -w '% {url_effective}' fonctionne très bien pour moi.
Eric Klien
5

Je vous remercie. J'ai fini par implémenter vos suggestions: 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

Renvoie vide si le site Web ne redirige pas, mais cela me suffit car il fonctionne sur des redirections consécutives.

Cela pourrait être bogué, mais en un coup d'œil, cela fonctionne bien.

vice
la source
2

Cela fonctionnerait:

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

Les paramètres -L (--location)et -I (--head)toujours faire une demande HEAD inutile à l'emplacement-url.

Si vous êtes sûr de ne pas avoir plus d'une redirection, il est préférable de désactiver la localisation de suivi et d'utiliser une variable curl% {redirect_url}.

Ce code ne fait qu'une seule demande HEAD à l'URL spécifiée et prend redirect_url de l'en-tête d'emplacement:

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

Test de rapidité

all_videos_link.txt - 50 liens de goo.gl + bit.ly qui redirigent vers youtube

1. Avec suivre l'emplacement

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

Résultats:

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

2. Sans suivre l'emplacement

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

Résultats:

real    0m51.037s
user    0m5.297s
sys     0m8.094s
Géographie
la source
Il semble assez rare que vous sachiez à l'avance qu'il n'y aurait qu'une seule redirection ...
SamB
1

Je ne sais pas comment le faire avec curl, mais libwww-perl installe l'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
la source
0

Pouvez-vous essayer avec?

#!/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"

Remarque: lorsque vous exécutez la commande curl -I http://votre-domaine.com doit utiliser des guillemets simples dans la commande comme curl -I 'http://your-domain.com'

lakshmikandan
la source
-3

Vous pouvez utiliser grep. ne vous dit-il pas où il redirige aussi? Grep juste ça.

Joint
la source