Bypass ReCAPTCHA Automatically Using Go

sponsored · Nov 8, 2021 · ~6 min
Photo by @agk42 on Unsplash
Photo by @agk42 on Unsplash

Introduction

A captcha sometimes could be annoying. It is even more annoying when you are working on automation software. A captcha, from a simple calculation, a slider captcha, HCpatcha, and ReCaptcha are not easy to be solved using automation. You may create a deep/machine learning model to solve the captcha. But, how about the training datasets? It will be bulky to work with the training datasets, or else, it will be hard. That’s why many sites use captcha to prevent automation/bot.

But, what if you have someone that would solve the captcha for you? Wouldn’t it be easier? You don’t need to think about solving the captcha and start focusing on the real problem. That’s where 2Captcha comes as a captcha solver. 2Captcha is a captcha solving software that may help you with solving captchas. 2Captcha has a varied library to work with various programming languages. So whatever languages you use, 2Captcha’s API is there for you.

In this sponsored article, you will learn how to bypass Google ReCaptcha using 2Captcha and Golang. You will also use Chromedp to automate the job. Here, I already have created a Github repository that you may want to clone.

Clone the Repository

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ git clone https://github.com/ClavinJune/2captcha-example
$ cd 2captcha-example/
$ tree .
.
├── go.mod
├── go.sum
├── main.go
├── Makefile
└── README.md

0 directories, 5 files

Usage

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$ go mod download
$ API_KEY=XXXXXXXX make run
2021/11/05 08:06:46 Status 200 OK data OK|684...
2021/11/05 08:06:59 Status 200 OK data CAPCHA_NOT_READY
2021/11/05 08:07:10 Status 200 OK data CAPCHA_NOT_READY
2021/11/05 08:07:21 Status 200 OK data CAPCHA_NOT_READY
2021/11/05 08:07:32 Status 200 OK data CAPCHA_NOT_READY
2021/11/05 08:07:44 Status 200 OK data CAPCHA_NOT_READY
2021/11/05 08:07:57 Status 200 OK data OK|03A...
2021/11/05 08:07:57 bypass recaptcha success 1m20.852741298s

Let me explain how the code works.

Main File

You may want to focus only on the main.go file because the other file is just supportive files.

Helper Function

13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
...

func wait(sel string) cdp.ActionFunc {
  return run(1*time.Second, cdp.WaitReady(sel))
}

func run(timeout time.Duration, task cdp.Action) cdp.ActionFunc {
  return runFunc(timeout, task.Do)
}

func runFunc(timeout time.Duration, task cdp.ActionFunc) cdp.ActionFunc {
  return func(ctx context.Context) error {
    ctx, cancel := context.WithTimeout(ctx, timeout)
    defer cancel()

    return task.Do(ctx)
  }
}

...

Captcha Solver

30
31
32
33
34
35
36
37
38
39
40
41
42
43
...

func solveReCaptcha(client *api2captcha.Client, targetURL, dataSiteKey string) (string, error) {
  c := api2captcha.ReCaptcha{
    SiteKey:   dataSiteKey,
    Url:       targetURL,
    Invisible: true,
    Action:    "verify",
  }

  return client.Solve(c.ToRequest())
}

...

solveRecaptcha solves your Google ReCAPTCHA using the 2Captcha Golang library which you can see the code and documentation here.

Chromedp Actions

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
...

func recaptchaDemoActions(client *api2captcha.Client) []cdp.Action {
  const targetURL string = "https://www.google.com/recaptcha/api2/demo"
  var siteKey string
  var siteKeyOk bool

  return []cdp.Action{
    run(5*time.Second, cdp.Navigate(targetURL)),
    wait(`[data-sitekey]`),
    wait(`#g-recaptcha-response`),
    wait(`#recaptcha-demo-submit`),
    run(time.Second, cdp.AttributeValue(`[data-sitekey]`, "data-sitekey", &siteKey, &siteKeyOk)),
    runFunc(5*time.Minute, func(ctx context.Context) error {
      if !siteKeyOk {
        return errors.New("missing data-sitekey")
      }

      token, err := solveReCaptcha(client, targetURL, siteKey)
      if err != nil {
        return err
      }

      return cdp.
        SetJavascriptAttribute(`#g-recaptcha-response`, "innerText", token).
        Do(ctx)
    }),
    cdp.Click(`#recaptcha-demo-submit`),
    wait(`.recaptcha-success`),
  }
}

...

Inside the recaptchaDemoActions, you can define your targetURL as for this example is Google ReCAPTCHA demo page.

Actions Explanation

49
  run(5*time.Second, cdp.Navigate(targetURL)),

Navigate to the targetURL and give it a timeout depending on your internet speed.

50
  wait(`[data-sitekey]`),

Wait for the element that has [data-sitekey] attribute which is the Google ReCAPTCHA site key that you will pass to the solveRecaptcha function.

51
  wait(`#g-recaptcha-response`),

Wait for the element where you can put the Google ReCAPTCHA solution that the solveRecaptcha function will provide.

52
  wait(`#recaptcha-demo-submit`),

Wait for the submit button element.

53
  run(time.Second, cdp.AttributeValue(`[data-sitekey]`, "data-sitekey", &siteKey, &siteKeyOk)),

Fetch the data-sitekey attribute from the [data-sitekey] element, then put it on the siteKey and siteKeyOk variables.

54
55
56
57
58
59
60
61
62
63
64
65
66
67
  runFunc(5*time.Minute, func(ctx context.Context) error {
    if !siteKeyOk {
      return errors.New("missing data-sitekey")
    }

    token, err := solveReCaptcha(client, targetURL, siteKey)
    if err != nil {
      return err
    }

    return cdp.
      SetJavascriptAttribute(`#g-recaptcha-response`, "innerText", token).
      Do(ctx)
  }),

If the siteKeyOk variable returns false, it means the siteKey is not found. Otherwise, you pass it to the solveRecaptcha function along with 2Captcha's client and your targetURL. The function blocks the flow until it returns the token. And then, you set the token as the #g-recaptcha-response element’s innerText.

68
  cdp.Click(`#recaptcha-demo-submit`),

Click the submit button right after the token is set.

69
  wait(`.recaptcha-success`),

Wait for the .recaptcha-success element that indicates that your captcha is successfully bypassed.

Main Function

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...

func main() {
  client := api2captcha.NewClient(os.Getenv("API_KEY"))
  actions := recaptchaDemoActions(client)

  opts := append(cdp.DefaultExecAllocatorOptions[:],
    cdp.WindowSize(1366, 768),
    cdp.Flag("headless", false),
    cdp.Flag("incognito", true),
  )

  allocCtx, allocCancel := cdp.NewExecAllocator(context.Background(), opts...)
  defer allocCancel()
  ctx, cancel := cdp.NewContext(allocCtx)
  defer cancel()

  start := time.Now()
  err := cdp.Run(ctx, actions...)
  end := time.Since(start)

  if err != nil {
    log.Println("bypass recaptcha failed:", err, end)
  } else {
    log.Println("bypass recaptcha success", end)
  }
}

...

To Use the 2Captcha’s services, you may need to provide the API Key. You can get the API Key by registering to the 2Captcha’s service here by using my referral link.

After you have set the 2Captcha’s client, pass it to the recaptchaDemoActions function to get your Chromedp actions. Optionally, You may set the opts on line 77 to configure your Chromedp flags. You can refer to the docs to see other options. Then, create the Chromedp context and run it. You may see the code’s output just like in the usage section.

Conclusion

After all the journey, you may find it interesting to solve the Google ReCAPTCHA automatically. You may want to use 2Captcha’s services to solve other captchas besides Google Recaptcha by referring to the docs. It is straightforward and super easy to use.

Thank you for reading!

· · ·

Love This Content?

Any kind of supports is greatly appreciated! Kindly support me via Bitcoin, Ko-fi, Trakteer, or just continue to read another content. You can write a response via Webmention and let me know the URL via Telegraph.

Drop Your Comment Below