在 curl 被重定向后获取最终 URL

我需要在页面重定向后获得最终的 URL,最好是使用 curl 或 wget。

例如,译自: 美国《科学》杂志网站(http://google.com) http://google.com :可以重定向到 译自: 美国《 http://www.google.com 》杂志网站(http://www.google.com)原著:

内容很容易获得(例如 curl --max-redirs 10 http://google.com -L) ,但是我只对最终的 url (在前一种情况下是 http://www.google.com)感兴趣。

有没有办法只使用 Linux 内置的工具来做到这一点? (仅命令行)

171456 次浏览

你可以使用 grep,我们没有告诉你它在哪里重定向吗。

我不确定如何使用 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

作为另一种选择:

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

但它不会超过第一个。

谢谢,我最终实现了您的建议: 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

如果网站没有重定向,返回空白,但这对我来说已经足够好了,因为它可以连续重定向。

可能有问题,但是一眼就能看出来。

curl-w选项和子变量 url_effective就是你 寻找。

差不多

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

更多信息

-L         Follow redirects
-s         Silent mode. Don't output anything
-o FILE    Write output to <file> instead of stdout
-w FORMAT  What to output after completion

更多

您可能还想添加 -I(即大写的 i) ,这将使命令不下载任何“主体”,但它也使用 HEAD 方法,这不是问题所包含的,并且有可能改变服务器的功能。有时服务器对 HEAD 的响应不好,即使它们对 GET 的响应很好。

谢谢,这对我很有帮助。我做了一些改进,并用一个助手脚本“ finalurl”包装了它:

#!/bin/bash
curl $1 -s -L -I -o /dev/null -w '%{url_effective}'
  • 输出到 /dev/null
  • -I实际上不下载,只是发现最终的 URL
  • -s静音模式,没有进度条

这使得从其他类似的脚本调用命令成为可能:

echo `finalurl http://someurl/`

你通常可以用 wget 做到这一点。另外,如果您添加 -O /dev/null,您将不会实际保存文件。

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

这种方法可行:

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

参数 -L (--location)-I (--head)仍然对 location-url 执行不必要的 HEAD 请求。

如果确定不会有多个重定向,那么最好禁用 follow location 并使用 curl 变量% { redirect _ url }。

这段代码只对指定的 URL 执行一个 HEAD 请求,并从 location-header 获取 redirect _ URL:

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

速度测试

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

你能试试吗?

#!/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'等命令中使用单引号

curl只能跟随 http 重定向。为了遵循 meta 刷新指令和 javascript 重定向,你需要一个成熟的浏览器,比如无头 chrome:

#!/bin/bash
real_url () {
printf 'location.href\nquit\n' | \
chromium-browser --headless --disable-gpu --disable-software-rasterizer \
--disable-dev-shm-usage --no-sandbox --repl "$@" 2> /dev/null \
| tr -d '>>> ' | jq -r '.result.value'
}

如果你没有安装铬合金,你可以在码头集装箱里使用:

#!/bin/bash
real_url () {
printf 'location.href\nquit\n' | \
docker run -i --rm --user "$(id -u "$USER")" --volume "$(pwd)":/usr/src/app \
zenika/alpine-chrome --no-sandbox --repl "$@" 2> /dev/null \
| tr -d '>>> ' | jq -r '.result.value'
}

像这样:

$ real_url http://dx.doi.org/10.1016/j.pgeola.2020.06.005
https://www.sciencedirect.com/science/article/abs/pii/S0016787820300638?via%3Dihub