【问题标题】:Get final URL after curl is redirected重定向 curl 后获取最终 URL
【发布时间】: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 内置工具来做到这一点? (仅限命令行)

【问题讨论】:

    标签: linux redirect curl wget


    【解决方案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 即可。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-09-08
                  • 2013-05-02
                  • 1970-01-01
                  • 2022-09-28
                  • 2017-07-11
                  相关资源
                  最近更新 更多