Logo of «2Captcha»To home page
Captcha bypass tutorials

Was this helpful?

How to bypass Tencent captcha using Playwright

Gregory Fisher
Gregory Fisher

Technical engineer

Tencent Captcha is a token-based protection system commonly found on sites built with Tencent Cloud infrastructure. The key challenge when automating this captcha is that simply passing the page URL is not enough. You must specify the exact URL of the captcha script (captchaScript), and after receiving the response, correctly inject two parameters: ticket and randstr.

In this guide, we will walk through how to automate Tencent Captcha in Playwright with Python: find the required parameters in the page code or network requests, send the task to the 2Captcha API, and properly inject the response tokens so the form accepts them as the result of a real user's actions.

What You Will Need

  • Python 3.7 or higher
  • Installed Playwright
  • 2Captcha account and API key
  • Target page URL with Tencent Captcha
  • Optional: proxy, if the site is sensitive to datacenter IP addresses

Step 1. Installing Dependencies

Install the required libraries and Playwright browsers:

bash Copy
pip install playwright 2captcha-python
playwright install chromium

Step 2. Browser Initialization and Parameter Discovery

Start by opening the page and waiting for the widget to appear. For debugging, use visible mode headless=False.

python Copy
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch(headless=False)
    page = browser.new_page()
    page.goto("https://example.com/target-page-with-tencent")
    
    # Wait for the Tencent Captcha widget or iframe to appear
    page.wait_for_selector("#tcaptcha_iframe, #tcaptcha_popup, [data-tencent-captcha]")

Two critically important parameters are needed for solving: appid and captchaScript.

How to find appid

It is usually stored in the data-appid attribute of the widget container or passed in the JavaScript initialization code. You can also find it in the Network tab in requests to captcha.qq.com or ssl.captcha.qq.com as the aid or appId parameter.

How to find captchaScript (MANDATORY)

Attention: The captchaScript parameter is mandatory for correct Tencent Captcha solving via the API. Without specifying the exact script URL that the site uses, the environment emulation will be incorrect, and the captcha will not be solved.

The script URL can be found in the Network tab by filtering requests for the word TCaptcha. Most commonly, sites use one of the following popular variants:

  1. https://turing.captcha.qcloud.com/TCaptcha.js (Standard / Default)
  2. https://ca.turing.captcha.qcloud.com/TCaptcha-global.js (Global CDN)
  3. https://global.captcha.gtimg.com/TCaptcha-global.js (Tencent Global CDN)
  4. https://captchacdn.tencentcloudcs.com/TCaptcha-global.js (Tencent Cloud CDN)

If the site uses a custom domain, simply copy the full script URL from the Network tab.

Step 3. Sending the Task to the API and Getting Tokens

We will use the official Python SDK. It automatically creates a task and polls the server until a result is obtained.

python Copy
from twocaptcha import TwoCaptcha

solver = TwoCaptcha('YOUR_API_KEY')

result = solver.tencent(
    appid='2047454578', # Replace with the real appid
    url='https://example.com/target-page-with-tencent',
    captchaScript='https://turing.captcha.qcloud.com/TCaptcha.js' # You must specify the correct URL
)

print(f"Result: {result}")
# Result contains 'code' (this is the ticket) and 'randstr'

Note: If you prefer asynchronous code, check out the official example of using async options in the repository: async_tencent_options.py (https://github.com/2captcha/2captcha-python/blob/master/examples/async/async_tencent_options.py).

Alternative (direct HTTP request via curl):

bash Copy
curl -X POST https://api.2captcha.com/createTask \
  -H "Content-Type: application/json" \
  -d '{
    "clientKey": "YOUR_API_KEY",
    "task": {
      "type": "TencentCaptchaTaskProxyless",
      "websiteURL": "https://example.com/target-page-with-tencent",
      "appID": "2047454578",
      "captchaScript": "https://turing.captcha.qcloud.com/TCaptcha.js"
    }
  }'

Step 4. Injecting Tokens into the Form

Tencent Captcha returns two values: ticket (the main token) and randstr (an additional string for validation). Both values must be injected into the page.

Usually, sites expect a JavaScript callback to be triggered, which passes this data back to the widget.

python Copy
ticket = result['code']
randstr = result.get('randstr', '@') # If randstr is absent, '@' is sometimes used

page.evaluate(f"""
    // 1. Inject tokens into hidden form fields (if the site uses classic form submission)
    const form = document.querySelector('form');
    
    let ticketField = form.querySelector('input[name="ticket"], input[name="tc_token"]');
    if (!ticketField) {{
        ticketField = document.createElement('input');
        ticketField.type = 'hidden';
        ticketField.name = 'ticket';
        form.appendChild(ticketField);
    }}
    ticketField.value = "{ticket}";

    let randstrField = form.querySelector('input[name="randstr"]');
    if (!randstrField) {{
        randstrField = document.createElement('input');
        randstrField.type = 'hidden';
        randstrField.name = 'randstr';
        form.appendChild(randstrField);
    }}
    randstrField.value = "{randstr}";

    // 2. Call the callback function (the name may differ, check the initialization code)
    // Often this is window.TencentCaptchaCallback or a similar function
    if (typeof window.TencentCaptchaCallback === 'function') {{
        window.TencentCaptchaCallback({{
            ticket: "{ticket}",
            randstr: "{randstr}",
            code: 0
        }});
    }}
""")

Step 5. Submitting the Form

After successfully injecting the tokens and triggering the callback, the form should unlock.

python Copy
page.click("button[type='submit']")
page.wait_for_load_state("networkidle")

browser.close()

Full Working Example (Python)

python Copy
from playwright.sync_api import sync_playwright
from twocaptcha import TwoCaptcha

API_KEY = "YOUR_API_KEY"
TARGET_URL = "https://example.com/target-page-with-tencent"
APP_ID = "2047454578" # Replace with the real one
CAPTCHA_SCRIPT = "https://turing.captcha.qcloud.com/TCaptcha.js" # Replace with the real script URL

def solve_tencent_captcha():
    solver = TwoCaptcha(API_KEY)

    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        page = browser.new_page()
        
        try:
            page.goto(TARGET_URL)
            page.wait_for_selector("#tcaptcha_iframe, #tcaptcha_popup, [data-appid]", timeout=10000)
            
            print("Sending task to API...")
            
            # Solve captcha with mandatory captchaScript parameter
            result = solver.tencent(
                appid=APP_ID,
                url=TARGET_URL,
                captchaScript=CAPTCHA_SCRIPT
            )
            
            ticket = result['code']
            randstr = result.get('randstr', '@')
            print(f"Token received! Ticket: {ticket[:20]}..., Randstr: {randstr}")
            
            # Inject tokens and trigger callback
            page.evaluate(f"""
                const form = document.querySelector('form') || document.body;
                
                let ticketField = form.querySelector('input[name="ticket"], input[name="tc_token"]');
                if (!ticketField) {{
                    ticketField = document.createElement('input');
                    ticketField.type = 'hidden';
                    ticketField.name = 'ticket';
                    form.appendChild(ticketField);
                }}
                ticketField.value = "{ticket}";

                let randstrField = form.querySelector('input[name="randstr"]');
                if (!randstrField) {{
                    randstrField = document.createElement('input');
                    randstrField.type = 'hidden';
                    randstrField.name = 'randstr';
                    form.appendChild(randstrField);
                }}
                randstrField.value = "{randstr}";

                if (typeof window.TencentCaptchaCallback === 'function') {{
                    window.TencentCaptchaCallback({{
                        ticket: "{ticket}",
                        randstr: "{randstr}",
                        code: 0
                    }});
                }}
            """)
            
            # Attempt to submit the form
            submit_btn = page.locator("button[type='submit'], input[type='submit']").first
            if submit_btn.is_visible():
                submit_btn.click()
                page.wait_for_load_state("networkidle")
                print("Form submitted successfully!")
            else:
                print("Submit button not found or form already processed by callback.")
                
            page.wait_for_timeout(3000) # Pause for visual verification
            
        except Exception as e:
            print(f"Error: {e}")
        finally:
            browser.close()

if __name__ == "__main__":
    solve_tencent_captcha()

Troubleshooting Common Issues

Issue Cause and Solution
Captcha is not solved or returns a behavior error You did not specify the captchaScript parameter or provided an incorrect URL. This is the most common mistake. Check the Network tab and make sure the script URL matches what the site loads.
AppID not found (returns None) The widget loads inside a dynamic iframe. Go to the Network tab, filter by aid or appId, and extract the value from the URL of the request to Tencent servers.
Form does not submit after token injection The site expects a specific callback function to be triggered. Check the page source code (search for new TencentCaptcha or TencentCaptchaCallback) and call the required function via page.evaluate, passing an object with ticket and randstr.
Script works in visible mode but fails in headless This is headless mode detection by the anti-bot system. Use masking libraries (e.g., playwright-stealth) or pass high-quality residential proxies to the API.

Conclusion

Automating Tencent Captcha in Playwright requires attention to detail. Unlike some other captchas, it is critically important here not only to find the appid but also to pass the correct captchaScript URL. Without this, the environment emulation will be incomplete, and the protection will block the solution.

After receiving the ticket and randstr pair from the API, you need to correctly inject them both as hidden form fields and through the JavaScript callback that the specific site expects. By following this guide and carefully checking the network requests of the target page, you will be able to reliably bypass Tencent Captcha in your automation projects.