重定向 curl 后获取最终 URL

Posted

技术标签:

【中文标题】重定向 curl 后获取最终 URL【英文标题】:Get final URL after curl is redirected 【发布时间】:2011-03-05 16:41:17 【问题描述】:

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

例如 http://google.com 可能会重定向到 http://www.google.com

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

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

【问题讨论】:

【参考方案1】:

curl-w option和子变量url_effective就是你 正在寻找。

类似

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

更多信息

-L 跟随重定向 -s 静默模式。不输出任何东西 -o FILE 将输出写入 而不是 stdout -w FORMAT 完成后输出什么

更多

您可能还想添加-I(即大写的i),这将使该命令不下载任何“正文”,但它也使用HEAD方法,这不是问题所在包括并冒着改变服务器功能的风险。有时服务器对 HEAD 的响应不佳,即使它们对 GET 响应良好。

【讨论】:

如果你不想要这个文件,你应该可以使用“-o /dev/null” 这是一个不错的选择,我从来不知道 curl 可以做到这一点!它永远不会让我感到惊讶:-) 这比 curl 更像是一个 shell 功能 @DanielStenberg 你需要-I 否则它会实际下载文件。 一些网站还需要一个带有curl -A ... 的欺骗用户代理来重定向到预期的位置。【参考方案2】:

谢谢,这对我有帮助。我做了一些改进并将其包装在一个帮助脚本“finalurl”中:

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

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

echo `finalurl http://someurl/`

【讨论】:

感谢这些想法。我在我的 .bashrc 文件中将其重写为终端使用作为一个函数,并且不需要该文件中的简洁选项,所以我使用长名称来自我记录:finalurl() curl --silent --location --head --output /dev/null --write-out '%url_effective' -- "$@"; 【参考方案3】:

作为另一种选择:

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

但它不会超过第一个。

【讨论】:

【参考方案4】:

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

如果网站不重定向,则返回空白,但这对我来说已经足够了,因为它适用于连续重定向。

可能有问题,但乍一看还可以。

【讨论】:

【参考方案5】:

您通常可以使用 wget 来执行此操作。 wget --content-disposition "url" 另外,如果您添加 -O /dev/null,您实际上不会保存文件。

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

【讨论】:

-O /dev/null 替换为仅-O-。更好:wget -O- --content-disposition example.com 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' 对我来说很好。【参考方案6】:

这可行:

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

【讨论】:

【参考方案7】:

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

如果您确定不会有多个重定向,最好禁用跟随位置并使用 curl 变量 %redirect_url。

此代码仅对指定 URL 执行一次 HEAD 请求,并从 location-header 获取 redirect_url:

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

速度测试

all_videos_link.txt - 重定向到 youtube 的 goo.gl+bit.ly 的 50 个链接

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

【讨论】:

您提前知道只有一个重定向似乎很罕见......【参考方案8】:

curl 只能跟随 http 重定向。要同时遵循元刷新指令和 javascript 重定向,您需要一个成熟的浏览器,例如 headless 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'

如果您没有安装 chrome,您可以从 docker 容器中使用它:

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

【讨论】:

【参考方案9】:

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

【讨论】:

【参考方案10】:

你可以试试吗?

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

【讨论】:

【参考方案11】:

你可以使用 grep。 wget 没有告诉你它也重定向到哪里吗?只需 grep 即可。

【讨论】:

以上是关于重定向 curl 后获取最终 URL的主要内容,如果未能解决你的问题,请参考以下文章

使用curl获取Location:重定向后url

获取页面重定向URL

从 url android 获取最终重定向的 url

Meteor:重定向后的最终位置/URL 是啥?

如何获取网站重定向目标网址(最终用户链接)

CURL 不遵循 301 重定向,我需要做啥?