Tencent Captcha Image Solving
Solve Tencent captcha challenges including grid selection, click challenges, and slide puzzles. Tencent captcha is widely used in Chinese platforms and applications.
Tencent Captcha is a comprehensive security system developed by Tencent, widely used across Chinese internet platforms including WeChat, QQ, and various Tencent services. It includes multiple challenge types such as image grid selection, object clicking, and slide puzzles to prevent automated access and ensure legitimate user interactions.
Captcha Type
Use the following captcha type identifier in your API requests:
"type": "TENCENT_IMAGE"
Challenge Types
| Type | Description |
|---|---|
| grid | Select matching images from grid |
| click | Click on specific objects |
| slide | Slide puzzle piece to complete |
You only need to provide the questionType parameter (e.g., "grid", "click", "slide").
The API automatically formats the question internally. Do not add prefixes like "tencent_grid:" to your
question text.
Request Format
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
captcha.type |
string | required | Must be "TENCENT_IMAGE" |
captcha.metadata.siteUrl |
string | required | URL where captcha appears |
captcha.metadata.siteKey |
string | optional | Tencent appId |
captcha.payload.images |
array | required | Array of base64-encoded images |
captcha.payload.question |
string | required | Question with type prefix |
captcha.payload.questionType |
string | required | "grid", "click", or "slide" |
captcha.payload.referenceImages |
array | optional | Reference images |
Example Request
const response = await fetch('https://solver-api.mydisct.com/createTask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
auth: { token: 'YOUR_API_KEY' },
context: { source: 'api', version: '1.0.0' },
captcha: {
type: 'TENCENT_IMAGE',
metadata: {
siteUrl: 'https://example.com',
siteKey: 'app_id_here'
},
payload: {
images: ['img1', 'img2', 'img3', 'img4', 'img5', 'img6'],
question: 'Select all images containing cars',
questionType: 'grid',
referenceImages: []
}
}
})
});
Response Format
Create Task Response (Processing)
{
"success": true,
"service": "MyDisct Solver",
"task": {
"id": "MyDisctSolver_abc123",
"status": "processing"
}
}
Fetch Result Response (Completed)
{
"success": true,
"service": "MyDisct Solver",
"task": {
"id": "MyDisctSolver_abc123",
"status": "completed",
"result": {
"answers": [0, 2, 4],
"timestamp": "2025-11-05T12:34:56.789Z"
}
}
}
Python Example
import requests
import time
def solve_tencent(images, question, question_type, site_url, api_key):
create_response = requests.post(
'https://solver-api.mydisct.com/createTask',
headers={'Content-Type': 'application/json', 'apikey': api_key},
json={
'auth': {'token': api_key},
'context': {'source': 'api', 'version': '1.0.0'},
'captcha': {
'type': 'TENCENT_IMAGE',
'metadata': {'siteUrl': site_url},
'payload': {
'images': images,
'question': question,
'questionType': question_type,
'referenceImages': []
}
}
}
)
create_data = create_response.json()
if not create_data['success']:
raise Exception(create_data['error']['message'])
task_id = create_data['task']['id']
while True:
time.sleep(3)
result_response = requests.post(
'https://solver-api.mydisct.com/fetchResult',
headers={'Content-Type': 'application/json', 'apikey': api_key},
json={'taskId': task_id}
)
result_data = result_response.json()
if result_data['task']['status'] == 'completed':
return result_data['task']['result']['answers']
elif result_data['task']['status'] == 'failed':
raise Exception('Captcha solving failed')
solution = solve_tencent(
images=['img1', 'img2', 'img3', 'img4', 'img5', 'img6'],
question='Select all images containing cars',
question_type='grid',
site_url='https://example.com',
api_key='YOUR_API_KEY'
)
print(f'Solution: {solution}')
Implementation Guide
Step 1: Extract Tencent Captcha Challenge
First, you need to extract the captcha challenge from Tencent platforms:
// Extract Tencent captcha images and question
function extractTencentCaptcha() {
const captchaContainer = document.querySelector('.tcaptcha-container') ||
document.querySelector('[class*="tcaptcha"]') ||
document.querySelector('.t-captcha');
if (!captchaContainer) return null;
const questionElement = captchaContainer.querySelector('.tcaptcha-question') ||
captchaContainer.querySelector('[class*="question"]');
const question = questionElement ? questionElement.textContent.trim() : '';
const imageElements = captchaContainer.querySelectorAll('img');
const images = [];
for (const img of imageElements) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
ctx.drawImage(img, 0, 0);
const base64 = canvas.toDataURL('image/jpeg').split(',')[1];
images.push(base64);
}
const questionType = question.toLowerCase().includes('slide') ||
question.toLowerCase().includes('swipe') ?
'slide' : 'grid';
const appId = captchaContainer.getAttribute('data-appid') ||
document.querySelector('input[name="appid"]')?.value;
return { question, images, questionType, appId };
}
const captchaData = extractTencentCaptcha();
Step 2: Send to API and Poll for Result
async function solveTencentCaptcha(images, question, questionType, siteUrl, appId) {
const createResponse = await fetch('https://solver-api.mydisct.com/createTask', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({
auth: { token: 'YOUR_API_KEY' },
context: { source: 'api', version: '1.0.0' },
captcha: {
type: 'TENCENT_IMAGE',
metadata: { siteUrl },
payload: {
images,
question,
questionType,
appId // Include if available
}
}
})
});
const createData = await createResponse.json();
if (!createData.success) {
throw new Error(createData.error.message);
}
const taskId = createData.task.id;
while (true) {
await new Promise(resolve => setTimeout(resolve, 3000)); // Wait 3 seconds
const resultResponse = await fetch('https://solver-api.mydisct.com/fetchResult', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': 'YOUR_API_KEY'
},
body: JSON.stringify({ taskId })
});
const resultData = await resultResponse.json();
if (resultData.task.status === 'completed') {
return resultData.task.result.answers;
} else if (resultData.task.status === 'failed') {
throw new Error('Tencent captcha solving failed');
}
}
}
const { images, question, questionType, appId } = extractTencentCaptcha();
const solution = await solveTencentCaptcha(images, question, questionType, 'https://example.com', appId);
console.log('Solution:', solution); // [0, 2, 4] for grid, [x, y, size] for slide
Step 3: Apply Solution to Tencent
function applyTencentSolution(solution, questionType) {
const captchaContainer = document.querySelector('.tcaptcha-container') ||
document.querySelector('[class*="tcaptcha"]');
if (questionType === 'grid') {
const imageTiles = captchaContainer.querySelectorAll('img');
solution.forEach(index => {
if (imageTiles[index]) {
const clickEvent = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true,
clientX: imageTiles[index].getBoundingClientRect().left + 10,
clientY: imageTiles[index].getBoundingClientRect().top + 10
});
imageTiles[index].dispatchEvent(clickEvent);
}
});
} else if (questionType === 'slide') {
const [x, y, size] = solution;
const slideHandle = captchaContainer.querySelector('.tcaptcha-slide-handle') ||
captchaContainer.querySelector('[class*="slide"]');
if (slideHandle) {
const containerRect = captchaContainer.getBoundingClientRect();
const handleRect = slideHandle.getBoundingClientRect();
const slideDistance = x - handleRect.left + containerRect.left;
const mouseDownEvent = new MouseEvent('mousedown', {
clientX: handleRect.left + handleRect.width / 2,
clientY: handleRect.top + handleRect.height / 2,
bubbles: true
});
const mouseMoveEvent = new MouseEvent('mousemove', {
clientX: handleRect.left + slideDistance,
clientY: handleRect.top + handleRect.height / 2,
bubbles: true
});
const mouseUpEvent = new MouseEvent('mouseup', {
clientX: handleRect.left + slideDistance,
clientY: handleRect.top + handleRect.height / 2,
bubbles: true
});
slideHandle.dispatchEvent(mouseDownEvent);
slideHandle.dispatchEvent(mouseMoveEvent);
slideHandle.dispatchEvent(mouseUpEvent);
}
}
setTimeout(() => {
const submitButton = captchaContainer.querySelector('.tcaptcha-submit') ||
document.querySelector('.submit-button');
if (submitButton) {
submitButton.click();
}
}, 1000);
}
applyTencentSolution(solution, questionType);
Best Practices
- Question text usually in Chinese - include as-is
- Provide questionType parameter - the API handles formatting automatically
- Include appId when available for better accuracy
- Grid challenges typically use 6 images
- Slide challenges return [x, y, size] coordinates with size information
- Poll every 3 seconds for faster response
- Implement proper error handling for failed tasks
Common Issues
Solution: Tencent frequently updates their captcha implementation. Check for new class names like 'tcaptcha-container' or 't-captcha'. The captcha may be in iframes.
Solution: Always include the question text exactly as displayed, including all Chinese characters. Do not translate or modify the text.
Solution: Check for keywords like "slide", "swipe", or "select" in the question text to properly determine the challenge type.
Solution: Ensure you're using the correct coordinate system. The slide solution includes [x, y, size] where size may be needed for proper positioning.
Solution: The appId is optional but improves accuracy. Look for it in data attributes or hidden inputs within the captcha container.