primp HTTP 客户端的 Go 语言绑定 —— 核心是 Rust,通过 C ABI + cgo 暴露给 Go。
⚠️ 当前版本仅支持 Windows amd64。在其它平台上构建会得到build constraints exclude all Go files的报错。
设计目标:在 Go 端获得与 primp-python 类似的使用体验,同时遵循 Go 习惯:
- ✅ 真正的命名枚举:
Impersonate/ImpersonateOS/Method都是int32命名常量(如primp.ImpersonateChromeV146),不是字符串。编译期就能拼写检查、IDE 跳转。 - ✅ 同步阻塞 API:
client.Get(url)直接返回*Response;并发由调用方用go关键字驱动。 - ✅ 函数式选项:用
WithJSON/WithHeaders/WithTimeout等覆盖 Python 关键字参数风格。 - ✅ 完整中文注释。
- ✅ 支持 Chrome / Edge / Safari / Firefox / Opera 多版本指纹模拟。
- ✅ 预编译静态库由 GitHub Actions 提供,调用方无需安装 Rust。
仓库内已经包含由 GitHub Actions 自动构建的 Windows 静态库(lib/windows_amd64/libprimp_go.a)和 C 头文件(include/primp.h),所以调用方只需要 Go 工具链(自带 MinGW gcc),不需要安装 Rust:
# 1. 在你的项目里
go get github.com/pll177/primp-go
# 2. 直接 build / run / test
go run .Go for Windows 的官方安装包自带 MinGW gcc,cgo 开箱即用。 如果你的环境里 cgo 不可用,先
go env -w CGO_ENABLED=1,并确保 PATH 里有 gcc(如装了 TDM-GCC 或 MSYS2 的 mingw64 工具链)。
package main
import (
"fmt"
"log"
"time"
primp "github.com/pll177/primp-go"
)
func main() {
client, err := primp.NewClient(primp.ClientOptions{
Impersonate: primp.ImpersonateChromeV146,
ImpersonateOS: primp.ImpersonateOSWindows,
Timeout: 10 * time.Second,
})
if err != nil {
log.Fatal(err)
}
defer client.Close()
resp, err := client.Get("https://httpbin.org/get?msg=hello")
if err != nil {
log.Fatal(err)
}
defer resp.Close()
fmt.Println("状态:", resp.StatusCode())
fmt.Println("URL: ", resp.URL())
fmt.Println("UA: ", resp.Headers()["User-Agent"])
}如果你要修改 Rust 端代码,需要 Rust toolchain ≥ 1.84:
rustup target add x86_64-pc-windows-gnu
cargo build --release --target x86_64-pc-windows-gnu
# 把产物拷到 cgo 期望的位置
mkdir lib\windows_amd64 -ErrorAction SilentlyContinue
copy target\x86_64-pc-windows-gnu\release\libprimp_go.a lib\windows_amd64\
# 然后跑 Go 端
go build .\...
go test .\...
go run .\examples\basic或者直接 push 到 main —— GitHub Actions 会自动重新编译并把新静态库 commit 回仓库。
无需创建 Client,适合一次性调用:
resp, err := primp.Get("https://httpbin.org/get")
resp, err := primp.Post("https://httpbin.org/post", primp.WithJSON(payload))
resp, err := primp.RequestOnce(primp.MethodPATCH, url, primp.WithContent(body))import "errors"
_, err := client.Get(url)
switch {
case errors.Is(err, primp.ErrTimeout):
// 超时
case errors.Is(err, primp.ErrConnect):
// 连接失败
case errors.Is(err, primp.ErrStatus):
var pe *primp.PrimpError
errors.As(err, &pe)
fmt.Println("HTTP", pe.Status, pe.Message)
}完整错误类型:ErrBuilder / ErrRequest / ErrConnect / ErrTimeout / ErrStatus / ErrRedirect / ErrBody / ErrDecode / ErrUpgrade / ErrGeneric。
Client 是线程安全的(内部 RwLock 保护),可在多个 goroutine 间共享:
client, _ := primp.NewClient(primp.ClientOptions{Impersonate: primp.ImpersonateChrome})
defer client.Close()
var wg sync.WaitGroup
for _, u := range urls {
wg.Add(1)
go func(u string) {
defer wg.Done()
resp, err := client.Get(u)
if err != nil { return }
defer resp.Close()
process(resp.Bytes())
}(u)
}
wg.Wait()| 常量 | 含义 |
|---|---|
ImpersonateNone |
不启用模拟(默认零值) |
ImpersonateChrome |
最新 Chrome |
ImpersonateChromeV144/145/146 |
指定 Chrome 版本 |
ImpersonateEdge / EdgeV144..146 |
Edge |
ImpersonateSafari / SafariV185/V26/V263 |
Safari |
ImpersonateFirefox / FirefoxV140/V146/V147/V148 |
Firefox |
ImpersonateOpera / OperaV126..129 |
Opera |
ImpersonateRandom |
随机一个 |
OS 指纹:ImpersonateOSAndroid / IOS / Linux / MacOS / Windows / Random / None。
| Python | Go |
|---|---|
Client(impersonate="chrome_146") |
NewClient(ClientOptions{Impersonate: ImpersonateChromeV146}) |
client.get(url, params=...) |
client.Get(url, WithParams(...)) |
client.post(url, json=payload) |
client.Post(url, WithJSON(payload)) |
r.json() / r.text / r.content |
r.JSON(&v) / r.Text() / r.Bytes() |
r.raise_for_status() |
r.RaiseForStatus() |
TimeoutError |
errors.Is(err, primp.ErrTimeout) |
with Client() as c: ... |
defer c.Close() |
primp-go/
├── Cargo.toml # Rust crate(staticlib)
├── build.rs, cbindgen.toml # cbindgen 生成 include/primp.h
├── src/ # Rust FFI 源码
├── include/primp.h # ← 由 CI 自动生成并 commit
├── lib/windows_amd64/
│ └── libprimp_go.a # ← 由 CI 自动构建并 commit
├── go.mod
├── enums.go errors.go ffi.go primp.go response.go
├── primp_test.go # 集成测试(联网,httpbin)
├── examples/basic/main.go
└── .github/workflows/build-libs.yml # 自动构建 + commit
- 🚫 Linux / macOS:计划但尚未提供预编译库
- 🚫 流式响应(
iter_bytes/iter_lines) - 🚫 multipart 文件上传(
files=) - 🚫
AsyncClient(异步在 Go 中不必要,直接go client.Get(...)即可)
MIT。primp 上游版权归 deedy5 所有。