Golang实现验证码采集器的开发与实践

Golang实现验证码采集器的开发与实践 我正在寻找一位开发者帮我制作一个验证码绕过包。

我希望程序能打开一个窗口,允许用户登录他们的谷歌账户(保存会话以便用于验证码解决…登录谷歌有助于获得一键验证码,无需点击图片)。

该窗口将保持打开状态,直到我使用函数让窗口加载验证码。该函数将包含以下参数:siteUrl 和 siteKey(网站的验证码密钥)…打开的页面将显示验证码供用户解决。一旦验证码被解决,g-captcha-response 令牌应保存到字典中,包含网站 URL 和解决时间…然后验证码应重新加载,以便用户可以再次解决,新的响应令牌可以被存储。

这样字典将包含多个网站的多个令牌。 siteUrl => g-captcha-response 令牌 => 解决时间

这样我就可以获取该网站 URL 的所有令牌。

如果您能完成这个项目,请告知我,如果可能的话,我希望使用这个包:https://github.com/asticode/go-astilectron

我找到了一个类似的 GitHub 仓库,它是用 NodeJS 编写的,您可以将其作为基础参考。

GitHub

dzt/captcha-harvester

协作式收集方法的可能计划 - dzt/captcha-harvester

avatar


更多关于Golang实现验证码采集器的开发与实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

你好Alex,

我可以提供帮助:anna(dot)cis23(at)gmail(dot)com

谢谢!

Anna

更多关于Golang实现验证码采集器的开发与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


以下是使用 Go 语言结合 go-astilectron 库实现验证码采集器的示例代码。该代码创建一个 Electron 窗口,允许用户登录 Google 账户,然后加载指定 URL 和 siteKey 的验证码,并在解决后存储 g-captcha-response 令牌。

首先,确保安装必要的依赖:

go mod init captcha-harvester
go get github.com/asticode/go-astilectron
go get github.com/asticode/go-astilectron-bootstrap

然后,创建 main.go 文件:

package main

import (
    "context"
    "fmt"
    "log"
    "sync"
    "time"

    "github.com/asticode/go-astilectron"
    bootstrap "github.com/asticode/go-astilectron-bootstrap"
)

// TokenStorage 存储验证码响应的结构
type TokenStorage struct {
    sync.RWMutex
    Tokens map[string][]TokenEntry
}

// TokenEntry 表示单个验证码响应条目
type TokenEntry struct {
    ResponseToken string
    SolvedAt      time.Time
}

var storage = &TokenStorage{
    Tokens: make(map[string][]TokenEntry),
}

// 添加令牌到存储
func (ts *TokenStorage) AddToken(siteURL, responseToken string) {
    ts.Lock()
    defer ts.Unlock()
    entry := TokenEntry{
        ResponseToken: responseToken,
        SolvedAt:      time.Now(),
    }
    ts.Tokens[siteURL] = append(ts.Tokens[siteURL], entry)
}

// 获取特定网站的所有令牌
func (ts *TokenStorage) GetTokens(siteURL string) []TokenEntry {
    ts.RLock()
    defer ts.RUnlock()
    return ts.Tokens[siteURL]
}

// 加载验证码的函数
func LoadCaptcha(siteURL, siteKey string) error {
    // 构建包含 reCAPTCHA 的 HTML 内容
    htmlContent := fmt.Sprintf(`
        <!DOCTYPE html>
        <html>
        <head>
            <script src="https://www.google.com/recaptcha/api.js" async defer></script>
        </head>
        <body>
            <div class="g-recaptcha" data-sitekey="%s" data-callback="onCaptchaSolved"></div>
            <script>
                function onCaptchaSolved(response) {
                    // 发送响应令牌回 Go 后端
                    if (window.astilectron) {
                        window.astilectron.sendMessage("captchaSolved", { siteUrl: "%s", responseToken: response });
                    }
                }
            </script>
        </body>
        </html>
    `, siteKey, siteURL)

    // 在现有窗口中加载 HTML
    if err := bootstrap.SendMessage(astilectron.EventDispatchers{Proxifier: "window"}, "loadCaptcha", htmlContent, func(m *bootstrap.MessageIn) {
        // 处理消息响应(如果需要)
    }); err != nil {
        return fmt.Errorf("发送加载验证码消息失败: %v", err)
    }
    return nil
}

// 处理消息的函数
func handleMessages(_ *astilectron.Window, m bootstrap.MessageIn) (payload interface{}, err error) {
    switch m.Name {
    case "captchaSolved":
        // 解析消息负载
        var data struct {
            SiteURL       string `json:"siteUrl"`
            ResponseToken string `json:"responseToken"`
        }
        if err := m.Unmarshal(&data); err != nil {
            log.Printf("解析 captchaSolved 消息失败: %v", err)
            return nil, err
        }
        // 存储令牌
        storage.AddToken(data.SiteURL, data.ResponseToken)
        log.Printf("验证码已解决,站点: %s, 令牌: %s", data.SiteURL, data.ResponseToken)
        
        // 可选:自动重新加载验证码以供再次解决
        // 这里可以调用 LoadCaptcha 重新加载,但注意避免无限循环
    }
    return nil, nil
}

func main() {
    // 使用 bootstrap 运行应用
    if err := bootstrap.Run(bootstrap.Options{
        AstilectronOptions: astilectron.Options{
            AppName:            "Captcha Harvester",
            AppIconDefaultPath: "resources/icon.png", // 可选图标路径
            AppIconDarwinPath:  "resources/icon.icns", // macOS 图标
            BaseDirectoryPath:  ".",
        },
        Windows: []*bootstrap.Window{{
            Homepage:       "https://accounts.google.com", // 初始加载 Google 登录页面
            MessageHandler: handleMessages,
            Options: &astilectron.WindowOptions{
                Center: astilectron.PtrBool(true),
                Height: astilectron.PtrInt(700),
                Width:  astilectron.PtrInt(1200),
            },
        }},
        OnWait: func(_ *astilectron.Astilectron, ws []*astilectron.Window, _ *astilectron.Menu, _ *astilectron.Tray, _ *astilectron.Menu) error {
            // 应用启动后,窗口已打开,保持运行直到关闭
            log.Println("应用已启动,窗口打开中...")
            return nil
        },
    }); err != nil {
        log.Fatalf("运行 bootstrap 失败: %v", err)
    }
}

使用说明:

  1. 初始化窗口:应用启动时打开一个 Electron 窗口,加载 Google 登录页面(https://accounts.google.com),用户可登录以简化验证码解决过程。
  2. 加载验证码:调用 LoadCaptcha 函数(可通过其他机制触发,如 HTTP 端点或内部事件),传入 siteUrlsiteKey。该函数动态生成包含 reCAPTCHA 的 HTML 并加载到窗口中。
  3. 处理验证码解决:当用户解决验证码时,JavaScript 回调 onCaptchaSolved 被触发,通过 astilectron 发送消息到 Go 后端,存储 g-captcha-response 令牌到 TokenStorage
  4. 存储令牌TokenStorage 使用映射结构,键为 siteUrl,值为 TokenEntry 切片,每个条目包含响应令牌和解决时间。
  5. 获取令牌:通过 storage.GetTokens(siteURL) 可检索特定网站的所有令牌。

示例调用 LoadCaptcha 函数:

在应用中,您可以通过事件或 API 触发验证码加载。例如,添加一个简单的 HTTP 服务器来接收请求:

import (
    "net/http"
)

func main() {
    // ... 上面的 bootstrap 代码 ...

    // 启动 HTTP 服务器以触发验证码加载
    http.HandleFunc("/load-captcha", func(w http.ResponseWriter, r *http.Request) {
        siteURL := r.URL.Query().Get("siteUrl")
        siteKey := r.URL.Query().Get("siteKey")
        if siteURL == "" || siteKey == "" {
            http.Error(w, "缺少 siteUrl 或 siteKey 参数", http.StatusBadRequest)
            return
        }
        if err := LoadCaptcha(siteURL, siteKey); err != nil {
            http.Error(w, fmt.Sprintf("加载验证码失败: %v", err), http.StatusInternalServerError)
            return
        }
        w.Write([]byte("验证码加载成功"))
    })

    log.Println("HTTP 服务器启动在 :8080")
    go http.ListenAndServe(":8080", nil)

    // 保持主线程运行
    select {}
}

运行应用后,访问 http://localhost:8080/load-captcha?siteUrl=example.com&siteKey=your_site_key 可触发验证码加载。解决后,令牌被存储,可通过 storage.GetTokens("example.com") 访问。

此实现基于 go-astilectron,提供了跨平台桌面应用功能,并参考了 Node.js 版本的逻辑。确保处理错误和边缘情况,如窗口管理和消息传递。

回到顶部