同一个 HTTP/2 网址,用 Python 的 httpx 请求直接成功,用 Golang 的 net/http 请求立刻 5 秒盾,大家有遇到过吗?

2021-08-18 10:38:39 +08:00
 mekingname

网址是: https://www.gizmochina.com/2021/06/23/redmi-gm-lu-weibing-stylishly-teases-the-redmi-k50-series

用 HTTPX 请求的代码如下,请求成功,状态码 200:

用 Golang 的 net/http 请求如下,请求失败,状态码 403:

如果你查看 httpx 返回的源代码和 net/http 的源代码,你会发现,用 httpx 返回的就是这个页面的源代码。而使用 net/http,返回的就是 CloudFlare 的 5 秒盾页面。

2770 次点击
所在节点    Go 编程语言
19 条回复
abersheeran
2021-08-18 10:40:59 +08:00
之前偶然看到过,golang 标准库的 TLS 好像实现有点特殊,大概 cf 是针对这个特殊的实现做了检测吧
ericls
2021-08-18 10:43:07 +08:00
抓包看看?
popstk
2021-08-18 10:43:17 +08:00
mekingname
2021-08-18 10:47:34 +08:00
@ericls 抓过了。我发现用 net/http 请求的报里面,有一些 pseudo-header,就是冒号开头的几个字段。而 httpx 的请求没有。

net/http 请求的包如下图所示:![]( https://kingname-1257411235.cos.ap-chengdu.myqcloud.com/20210818104656.png)

httpx 请求的包如下图所示:![]( https://kingname-1257411235.cos.ap-chengdu.myqcloud.com/20210818104725.png)
mekingname
2021-08-18 11:04:41 +08:00
@popstk 它这个方案我也试过了。单纯改 CipherSuites 还过不了。
des
2021-08-18 11:11:27 +08:00
cf 检测机制的问题吧,建议你再重新用 httpx 试试,我这边两个都 403
mekingname
2021-08-18 11:15:33 +08:00
@des 我又测试了很多次,只设置 User-Agent 就能得到正确的返回。
emeab
2021-08-18 11:15:45 +08:00
@mekingname golang 的 TLS1.3 请求好像不能改 CipherSuites
des
2021-08-18 11:19:02 +08:00
@mekingname 建议用 curl 测试
mekingname
2021-08-18 11:21:00 +08:00
@emeab 那还有救吗
emeab
2021-08-18 11:23:54 +08:00
@mekingname 把他锁到 1.2 看看. 1.3 不支持配置 CipherSuites
mekingname
2021-08-18 11:24:03 +08:00
@des curl 是会失败。
mekingname
2021-08-18 11:39:45 +08:00
@emeab 锁定不住。我试过了两种锁定 TLS 版本的办法,但是它总是自动使用 1.3
wothard
2021-08-18 17:06:53 +08:00
net/http 不支持 http2 吧,试试用这个包 https://pkg.go.dev/golang.org/x/net/http2
Kisesy
2021-08-18 18:52:50 +08:00
试了一下,可以跳过,首先设置 UA,然后设置 tls 版本到 1.2,再设置 http.Transport 的 ForceAttemptHTTP2 为假
强制 http1 访问,就可以了
humxman
2021-08-18 19:53:52 +08:00
@Kisesy 你这样对设置了 Minimum TLS1.2 的网站不行的吧。
yin1999
2021-08-19 06:58:46 +08:00
@wothard 支持的:The http package's Transport and Server both automatically enable HTTP/2 support for simple configurations.
mekingname
2021-08-19 10:26:42 +08:00
@wothard net/http2 Overview 的第二段就写明白了:

> This package is low-level and intended to be used directly by very few people. Most users will use it indirectly through the automatic use by the net/http package (from Go 1.6 and later)

直接使用 net/http 就可以了。它遇到 http2 页面自动会在底层调用 net/http2,常规请求不需要开发者手动使用。
forrestshuang
2023-03-09 17:53:46 +08:00
// 我成功了,代码在这里
package main

import (
"crypto/tls"
"fmt"
"net/http"
)

func main() {
defaultCipherSuites := []uint16{0xc02f, 0xc030, 0xc02b, 0xc02c, 0xcca8, 0xcca9, 0xc013, 0xc009,
0xc014, 0xc00a, 0x009c, 0x009d, 0x002f, 0x0035, 0xc012, 0x000a}
client := http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
CipherSuites: append(defaultCipherSuites[8:], defaultCipherSuites[:8]...),
MaxVersion: tls.VersionTLS12,
},
ForceAttemptHTTP2: false,
},
}
req, err := http.NewRequest("GET", "", nil)

req.Header.Add("authority", "api.nftgo.io")
req.Header.Add("pragma", "no-cache")
req.Header.Add("User-Agent", "Apifox/1.0.0 ( https://www.apifox.cn)")

resp, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
fmt.Println(resp.Status)
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/796484

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX