How to Solve Yandex Puzzle Captcha: Complete Guide
Learn how to automatically solve Yandex SmartCaptcha (Puzzle/Slider type) using our API. This guide covers parameter extraction with regex, C# examples, and API integration.
1. What is Yandex Puzzle Captcha?
Yandex Puzzle Captcha (also known as Kaleidoscope or Slider captcha) requires users to drag a puzzle piece to complete an image. The challenge is to determine the correct horizontal position (step number) where the piece fits perfectly.
2. Extracting Parameters from Page HTML
To solve a Yandex Puzzle captcha, you need to extract two key parameters from the page HTML:
- imageSrc - URL of the puzzle background image
- task - array of numbers representing the puzzle pattern, e.g. [6,8,2,7,0,6,8,0,3,2,8,3,3,0,1,5,2,7,8,6,6,2,6,1,2,6]
2.1 Regex Patterns for Parameter Extraction
Use these proven regex patterns to extract captcha parameters from JavaScript/HTML:
C# Regex Patterns (Compiled)
Extract task array:
task:""\[(.*?)\]""
Extract imageSrc URL:
imageSrc:""(.*?)""
Full C# Example:
using System.Text.RegularExpressions;
// Compiled regex patterns for performance
private static readonly Regex _captchaTasks = new(
@"task:""\[(.*?)\]""",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex _captchaUrl = new(
@"imageSrc:""(.*?)""",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
public static (string? imageUrl, string? taskArray) ExtractPuzzleParams(string html)
{
var taskMatch = _captchaTasks.Match(html);
var urlMatch = _captchaUrl.Match(html);
string? task = taskMatch.Success ? $"[{taskMatch.Groups[1].Value}]" : null;
string? imageUrl = urlMatch.Success ? urlMatch.Groups[1].Value : null;
return (imageUrl, task);
}
2.2 Downloading the Puzzle Image
public static async Task<byte[]> DownloadPuzzleImageAsync(string imageUrl)
{
using var client = new HttpClient();
return await client.GetByteArrayAsync(imageUrl);
}
// Usage
var (imageUrl, task) = ExtractPuzzleParams(htmlContent);
if (!string.IsNullOrEmpty(imageUrl) && !string.IsNullOrEmpty(task))
{
var imageBytes = await DownloadPuzzleImageAsync(imageUrl);
// Save to file if needed
await File.WriteAllBytesAsync("puzzle.png", imageBytes);
}
3. Solving with noncaptcha API
Once you have the puzzle image and task array, send them to our API endpoint:
3.1 API Endpoint
Parameter Type Description
captcha file Puzzle background image (PNG/JPG)
task string Task array as JSON string, e.g. "[6,8,2,7,0,6,8,0,3,2,8,3,3,0,1,5,2,7,8,6,6,2,6,1,2,6]"
3.2 cURL Example
curl -X POST "http://api.noncaptcha.com/api/json/puzzle" \
-H "X-API-Key: YOUR_API_KEY" \
-F "captcha=@puzzle.png" \
-F "task=[6,8,2,7,0,6,8,0,3,2,8,3,3,0,1,5,2,7,8,6,6,2,6,1,2,6]"
3.3 C# Example (Complete)
using System.Net.Http;
using System.Text;
using System.Text.Json;
public async Task<int> SolveYandexPuzzleAsync(
string apiKey,
string imagePath,
string taskArray)
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
var content = new MultipartFormDataContent();
// Add puzzle image
var imageBytes = await File.ReadAllBytesAsync(imagePath);
var imageContent = new ByteArrayContent(imageBytes);
imageContent.Headers.ContentType =
new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
content.Add(imageContent, "captcha", Path.GetFileName(imagePath));
// Add task array as string
content.Add(new StringContent(taskArray, Encoding.UTF8), "task");
// Send request
var response = await client.PostAsync(
"http://api.noncaptcha.com/api/json/puzzle",
content
);
response.EnsureSuccessStatusCode();
// Parse response: {"step": 12}
var jsonResponse = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(jsonResponse);
return doc.RootElement.GetProperty("step").GetInt32();
}
3.4 Full Integration: Extract + Solve
public class YandexPuzzleSolver
{
private readonly HttpClient _client;
private readonly string _apiKey;
// Compiled regex patterns
private static readonly Regex _captchaTasks = new(
@"task:""\[(.*?)\]""",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex _captchaUrl = new(
@"imageSrc:""(.*?)""",
RegexOptions.IgnoreCase | RegexOptions.Compiled);
public YandexPuzzleSolver(string apiKey)
{
_apiKey = apiKey;
_client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
_client.DefaultRequestHeaders.Add("X-API-Key", apiKey);
}
public async Task<int?> SolveFromHtmlAsync(string htmlContent)
{
// 1. Extract parameters using regex
var taskMatch = _captchaTasks.Match(htmlContent);
var urlMatch = _captchaUrl.Match(htmlContent);
if (!taskMatch.Success || !urlMatch.Success)
return null;
string taskArray = $"[{taskMatch.Groups[1].Value}]";
string imageUrl = urlMatch.Groups[1].Value;
// 2. Download puzzle image
var imageBytes = await _client.GetByteArrayAsync(imageUrl);
// 3. Prepare multipart request
var content = new MultipartFormDataContent();
content.Add(new ByteArrayContent(imageBytes), "captcha", "puzzle.png");
content.Add(new StringContent(taskArray, Encoding.UTF8), "task");
// 4. Send to API
var response = await _client.PostAsync(
"http://api.noncaptcha.com/api/json/puzzle",
content
);
// 5. Parse and return step number
var json = await response.Content.ReadAsStringAsync();
using var doc = JsonDocument.Parse(json);
return doc.RootElement.GetProperty("step").GetInt32();
}
public void Dispose() => _client?.Dispose();
}
// Usage example:
using var solver = new YandexPuzzleSolver("YOUR_API_KEY");
var html = await httpClient.GetStringAsync("https://example.com/page-with-captcha");
var step = await solver.SolveFromHtmlAsync(html);
if (step.HasValue)
{
Console.WriteLine($"✅ Move slider to step: {step.Value}");
// Use step to click slider buttons or move slider element
}
else
{
Console.WriteLine("❌ Failed to extract captcha parameters");
}
4. Using the Solution: Moving the Slider
After receiving the step number from the API, you need to simulate user interaction to move the puzzle slider to the correct position.
// Example using Playwright for browser automation
public async Task MoveSliderToStepAsync(IPage page, int step)
{
// Wait for slider controls
var nextBtn = await page.WaitForSelectorAsync(
"button[aria-label*='Сдвинуть'], button[aria-label*='Move']",
new() { Timeout = 10000 });
var slider = await page.WaitForSelectorAsync("#captcha-slider");
var submitBtn = await page.WaitForSelectorAsync("button[data-testid='submit']");
// Click 'next' button 'step' times with human-like delays
var random = new Random();
for (int i = 0; i < step; i++)
{
await nextBtn.ClickAsync();
await Task.Delay(random.Next(100, 400)); // Human-like delay
}
// Small random pause before submit
await Task.Delay(random.Next(300, 900));
// Click submit button
await submitBtn.ClickAsync();
// Wait for navigation or captcha disappearance
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
}
5. Error Handling & Best Practices
Retry Example (C# with Polly)
using Polly;
var retryPolicy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r =>
r.StatusCode == System.Net.HttpStatusCode.RequestTimeout ||
(int)r.StatusCode >= 500)
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: attempt =>
TimeSpan.FromSeconds(Math.Pow(2, attempt)),
onRetry: (outcome, timespan, attempt, context) =>
{
Console.WriteLine($"Retry {attempt} after {timespan}s");
});
// Usage:
var response = await retryPolicy.ExecuteAsync(async () =>
{
return await client.PostAsync(url, content);
});
6. Troubleshooting
| Issue | Solution |
|---|---|
Regex doesn't match |
Check if page uses dynamic JS rendering. Use Playwright/Puppeteer to get final HTML. |
API returns 402 |
Insufficient balance. Add funds via dashboard or check billing settings. |
Slider doesn't move correctly |
Ensure you're clicking the correct button selector. Yandex may update their DOM structure. |
Step number seems wrong |
Some captchas require step-1 adjustment. Test with known examples first. |
Need Help?
If you're having trouble with a specific captcha implementation, contact our support team with the page URL and HTML snippet.
Contact Support