重定向 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 将输出写入更多
您可能还想添加-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的主要内容,如果未能解决你的问题,请参考以下文章