Получить конечный URL после перенаправления curl

112

Мне нужно получить конечный URL-адрес после перенаправления страницы, желательно с помощью curl или wget.

Например, http://google.com может перенаправлять на http://www.google.com .

Содержимое легко получить (например curl --max-redirs 10 http://google.com -L), но меня интересует только конечный URL (в первом случае http://www.google.com ).

Есть ли способ сделать это, используя только встроенные инструменты Linux? (только командная строка)

тиски
источник

Ответы:

194

curl«S -wвариант и переменная к югу url_effectiveявляется то , что вы ищете.

Что-то вроде

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

Больше информации

-L Следовать перенаправлениям
-s Тихий режим. Ничего не выводить
-o ФАЙЛ Записывать вывод в <файл> вместо стандартного вывода
-w ФОРМАТИРОВАТЬ Что выводить после завершения

Больше

Вы также можете добавить -I(это в верхнем регистре i), что заставит команду не загружать никакого «тела», но тогда она также использует метод HEAD, который не входит в вопрос, и рискует изменить то, что делает сервер. Иногда серверы плохо реагируют на HEAD, даже если они хорошо реагируют на GET.

Даниэль Стенберг
источник
4
вы должны иметь возможность использовать "-o / dev / null", если вам не нужен файл
Гэвин Моган,
1
Это отличный вариант, я никогда не знала, что curl на это способен! Это никогда не перестает меня удивлять,:-)
Джош
1
Это скорее функция оболочки, чем curl
user151841
1
@DanielStenberg вам нужен, -Iиначе он фактически загрузит файл.
Стивен Пенни
2
Некоторым веб-сайтам также требуется поддельный пользовательский агент curl -A ...для перенаправления в ожидаемое место.
Иван Козик
30

Спасибо, мне это помогло. Я сделал некоторые улучшения и обернул это во вспомогательный скрипт finalurl:

#!/bin/bash
curl $1 -s -L -I -o /dev/null -w '%{url_effective}'
  • -o вывод на /dev/null
  • -I на самом деле не скачивайте, просто найдите конечный URL
  • -s тихий режим, без индикаторов выполнения

Это позволило вызвать команду из других скриптов, например:

echo `finalurl http://someurl/`
Ян Кориняк
источник
2
Спасибо за идеи. Я переписал его для использования терминалом в моем файле .bashrc как функцию, и нет необходимости в кратких параметрах в этом файле, поэтому я использовал длинные имена, чтобы самодокументировать это:finalurl() { curl --silent --location --head --output /dev/null --write-out '%{url_effective}' -- "$@"; }
gw0
7

как другой вариант:

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

Но не проходит мимо первого.

Гэвин Моган
источник
6

Обычно это можно сделать с помощью wget. wget --content-disposition"url" дополнительно, если вы добавите, -O /dev/nullвы не будете фактически сохранять файл.

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

Ceagle
источник
Заменить -O /dev/nullтолько с на -O-. Лучше:wget -O- --content-disposition example.com
Maxwel Leite
1
wget -O / dev / null --content-disposition example.com и wget -O- / dev / null --content-disposition example.com выдают намного больше результатов, чем перенаправленный URL. curl $ 1 -s -L -I -o / dev / null -w '% {url_effective}' у меня отлично работает.
Eric Klien
5

Спасибо. В итоге я реализовал ваши предложения: 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

Возвращает пустое значение, если веб-сайт не перенаправляет, но для меня этого достаточно, поскольку он работает с последовательными перенаправлениями.

Могут быть ошибки, но на первый взгляд все работает нормально.

тиски
источник
2

Это сработает:

 curl -I somesite.com | perl -n -e '/^Location: (.*)$/ && print "$1\n"'
Майк Кью
источник
2

Параметры -L (--location)и -I (--head)все еще делают ненужный HEAD-запрос к URL-адресу местоположения.

Если вы уверены, что у вас будет не более одного редиректа, лучше отключить отслеживание местоположения и использовать переменную curl% {redirect_url}.

Этот код выполняет только один HEAD-запрос к указанному URL-адресу и берет redirect_url из заголовка местоположения:

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

Тест скорости

all_videos_link.txt - 50 ссылок goo.gl + bit.ly, которые перенаправляют на YouTube

1. С указанием местоположения

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

Полученные результаты:

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

2. Без указания местоположения

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

Полученные результаты:

real    0m51.037s
user    0m5.297s
sys     0m8.094s
География
источник
Кажется довольно необычным, что вы заранее знали, что будет только один редирект ...
SamB
1

Я не уверен, как это сделать с помощью curl, но libwww-perl устанавливает псевдоним 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
Гэвин Моган
источник
0

Можешь попробовать?

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

Примечание: при выполнении команды curl -I http://your-domain.com необходимо использовать одинарные кавычки в команде, например curl -I 'http://your-domain.com'

лакшмикандан
источник
-3

Вы можете использовать grep. wget не сообщает вам, куда он перенаправляется? Просто найдите это.

SpliFF
источник