Obtenha o URL final depois que curl for redirecionado

110

Preciso obter o URL final após um redirecionamento de página, de preferência com curl ou wget.

Por exemplo, http://google.com pode redirecionar para http://www.google.com .

O conteúdo é fácil de obter (ex. curl --max-redirs 10 http://google.com -L), Mas estou interessado apenas no url final (no primeiro caso http://www.google.com ).

Existe alguma maneira de fazer isso usando apenas ferramentas integradas do Linux? (apenas linha de comando)

torno
fonte

Respostas:

191

curlA -wopção de e a subvariável url_effectiveé o que você está procurando.

Algo como

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

Mais informações

-L Seguir redirecionamentos
-s Modo silencioso. Não produza nada
-o FILE Grava a saída em <file> em vez de stdout
-w FORMAT O que produzir após a conclusão

Mais

Você pode querer adicionar -I(isto é, em maiúsculas i) também, o que fará com que o comando não baixe nenhum "corpo", mas ele também usa o método HEAD, que não é o que a pergunta inclui e corre o risco de alterar o que o servidor faz. Às vezes, os servidores não respondem bem ao HEAD, mesmo quando respondem bem ao GET.

Daniel Stenberg
fonte
4
você deve ser capaz de usar "-o / dev / null" se não quiser o arquivo
Gavin Mogan
1
Essa é uma ótima opção, eu nunca soube que o curl poderia fazer isso! Isso nunca para de me surpreender:-)
Josh
1
Isso é mais um recurso de shell do que curl
user151841
1
@DanielStenberg você precisa, -Icaso contrário, ele realmente baixará o arquivo.
Steven Penny
2
Alguns sites também precisam de um agente de usuário falsificado curl -A ...para redirecionar para o local esperado.
Ivan Kozik,
29

Obrigado, isso me ajudou. Fiz algumas melhorias e envolvi isso em um script auxiliar "finalurl":

#!/bin/bash
curl $1 -s -L -I -o /dev/null -w '%{url_effective}'
  • -o saída para /dev/null
  • -I não faça o download, apenas descubra o URL final
  • -s modo silencioso, sem barras de progresso

Isso tornou possível chamar o comando de outros scripts como este:

echo `finalurl http://someurl/`
Jan Koriťák
fonte
2
Obrigado por essas idéias. Reescrevi-o para uso de terminal em meu arquivo .bashrc como uma função e não há necessidade de opções concisas nesse arquivo, então usei os nomes longos para finalurl() { curl --silent --location --head --output /dev/null --write-out '%{url_effective}' -- "$@"; }
autodocumentar
7

como outra opção:

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

Mas não passa do primeiro.

Gavin Mogan
fonte
6

Você pode fazer isso com wget normalmente. wget --content-disposition"url" adicionalmente, se você adicionar -O /dev/null, não estará realmente salvando o arquivo.

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

Ceagle
fonte
Substitua -O /dev/nullapenas de para -O-. Melhor:wget -O- --content-disposition example.com
Maxwel Leite de
1
wget -O / dev / null --content-disposition example.com e wget -O- / dev / null --content-disposition example.com produzem muito mais saída do que a URL redirecionada. curl $ 1 -s -L -I -o / dev / null -w '% {url_effective}' funciona bem para mim.
Eric Klien
5

Obrigado. Acabei implementando suas sugestões: 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

Retorna em branco se o site não redirecionar, mas isso é bom o suficiente para mim, pois funciona em redirecionamentos consecutivos.

Pode ser um bug, mas à primeira vista funciona bem.

torno
fonte
2

Isso funcionaria:

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

Os parâmetros -L (--location)e-I (--head) ainda fazendo HEAD-request desnecessária para o location-url.

Se você tem certeza de que não terá mais de um redirecionamento, é melhor desabilitar o local de seguimento e usar uma variável curl% {redirect_url}.

Este código faz apenas uma solicitação HEAD para o URL especificado e pega redirect_url do cabeçalho do local:

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

Teste rápido

all_videos_link.txt - 50 links de goo.gl + bit.ly que redirecionam para o youtube

1. Com seguir localização

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. Sem seguir localização

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
fonte
Parece muito incomum saber de antemão que haveria apenas um redirecionamento ...
SamB
1

Não tenho certeza de como fazer isso com curl, mas libwww-perl instala o 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
fonte
0

Você pode tentar com isso?

#!/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: quando você executa o comando curl -I http://seu-domínio.com tem que usar aspas simples no comando, como curl -I 'http://your-domain.com'

Lakshmikandan
fonte
-3

Você pode usar grep. não vamos dizer para onde ele está redirecionando também? Basta ver isso.

SpliFF
fonte