因为某种需求,需要获取某篇文章在302跳转后真正的URL地址,既然需求有了就需要来解决,在看了网上各种的解决方法后觉得有些复杂,因此就有了以下的解决方法,如果这个方法不好,或有更好的解决方法欢迎在评论出指出,谢谢.

https://toutiao.io/j/48jhdt 为例, 在访问这个地址的时候会发送一个get请求,然后响应一个location真实地址,接着会再发送一个get请求去获取真实地址中的数据,因此只要能够拿到最后一次的get请求就可以得到真实的访问链接.

在go中访问url会返回Response指针和error,其中Response结构体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
type Response struct {
Status string // e.g. "200 OK"
StatusCode int // e.g. 200
Proto string // e.g. "HTTP/1.0"
ProtoMajor int // e.g. 1
ProtoMinor int // e.g. 0
Header Header
Body io.ReadCloser
...
Request *Request
...
}

在Response结构体中包裹了Request指针,而Request的结构体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
type Request struct {
// Method specifies the HTTP method (GET, POST, PUT, etc.).
// For client requests an empty string means GET.
Method string
URL *url.URL
Proto string // "HTTP/1.0"
ProtoMajor int // 1
ProtoMinor int // 0
Header Header
Body io.ReadCloser
ContentLength int64
...
Cancel <-chan struct{}
}

在上面可以看出,Request结构体中包含了url指针,因此就可以获取到页面的真实地址,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package main
import (
"fmt"
"net/http"
"os"
)
func main() {
resp,err := http.Get("https://toutiao.io/j/48jhdt")
checkErr(err)
request := resp.Request
fmt.Println(request.URL)
}
func checkErr(err error) {
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}