Captcha bypass tutorials

Was this helpful?

How to bypass Rotate Slider captcha on OOCL website

Gregory Fisher
Gregory Fisher

Technical engineer

Introduction

Rotate Slider captcha is an advanced verification method where the user needs to rotate an image to align it with a target fragment. This type of captcha is actively used on sites like OOCL.com to protect against automated access. Manual solving significantly slows down workflows, but you can fully automate it using the site_name API.

In this guide, we will break down the complete bypass cycle: from extracting images from HTML5 Canvas to physically moving the slider using mouse emulation.

Task Parameters

To solve Rotate Slider captcha, you can use the rotate_slider method (API V1) or the RotateSliderTask task type (API V2). The working example below uses API V1.

json Copy
{
  "method": "rotate_slider",
  "key": "YOUR_API_KEY",
  "body": "BASE64_MAIN_IMAGE",
  "part1": "BASE64_FRAGMENT_IMAGE",
  "json": 1
}

How to find parameters (Extracting images from Canvas)

Unlike classic captchas, images for Rotate Slider are often rendered dynamically inside HTML canvas elements. They cannot be simply downloaded via a direct link from the Network tab.

Instead, we extract them directly from the DOM tree using the JavaScript toDataURL() method:

  1. The main image (the background to which the fragment needs to be aligned) is usually in the first canvas: document.getElementsByTagName('canvas')[0].
  2. The fragment image (the rotating part) is in the second canvas: document.getElementsByTagName('canvas')[1].

After obtaining the Data URL, you must remove the data:image/png;base64, prefix to send a clean Base64 string to the API.

Code Example (Python + SeleniumBase + PyAutoGUI)

Below is a complete working script to bypass Rotate Slider CAPTCHA on OOCL.com.

The script uses SeleniumBase to control the browser, extracts images from the canvas, sends them to the site_name API, calculates the exact rotation angle, and uses pyautogui for physical mouse drag emulation.

python Copy
import base64
import json
import os
import random
import time
from pprint import pprint
import requests
from selenium.webdriver.common.by import By
from seleniumbase import SB
import pyautogui

my_key = "YOUR_API_KEY" # Specify your API key

url = "https://www.oocl.com/eng/ourservices/eservices/cargotracking/Pages/cargotracking.aspx"

# Initialize browser with anti-bot protection bypass (undetected-chromedriver)
with SB(uc=True, headless=False, proxy=False, locale_code='en') as sb:
    sb.set_window_position(0, 0)
    sb.set_window_size(800, 800)
    sb.uc_open_with_reconnect(url, 15)

    print("Enter to site...")
    try:
        sb.click('button[id="allowAll"]') # Close cookies banner
    except: pass
    
    # Interact with the site to trigger the captcha
    sb.type("input[id='SEARCH_NUMBER']", "res")
    sb.click("a[id='container_btn']")
    time.sleep(10)
    
    # Captcha opens in a new tab
    sb.switch_to_window(sb.driver.window_handles[1])
    sb.set_window_position(0, 0)

    try:
        # 1. Extract images from canvas
        base64_1 = sb.execute_script("return document.getElementsByTagName('canvas')[0].toDataURL()")
        base64_2 = sb.execute_script("return document.getElementsByTagName('canvas')[1].toDataURL()")
        
        # Remove prefix data:image/png;base64,
        base64_1 = base64_1.replace('data:image/png;base64,', '')
        base64_2 = base64_2.replace('data:image/png;base64,', '')
        print("IMAGES received")

        # 2. Send images to site_name API
        data = {
          "method": "rotate_slider",
          "key": my_key,
          "body": base64_1,
          "part1": base64_2,
          "json": 1
        }
        response = requests.post(f"https://api.2captcha.com/in.php?", json=data)
        print(response.text)
        s = response.json()["request"]
        
        # 3. Wait for solution
        time.sleep(7)
        while True:
          result = requests.post(f"https://api.2captcha.com/res.php?key={my_key}&action=get&json=1&id={s}").json()
          if result['request'] == 'CAPCHA_NOT_READY':
            print(result['request'])
            time.sleep(3)
          else:
            break
        pprint(result)
        
        # 4. Calculate rotation angle
        position = float(result['request']['angle'])
        center_x = int(result['request']['center'][0])
        center_y = int(result['request']['center'][1])
        point_circle = int(result['request']['point_circle'][1])
        
        # Logic to determine rotation direction (clockwise or counterclockwise)
        if (center_x <= 161 and point_circle > center_y) or (center_x > 161 and point_circle <= center_y):
            angle = 360 - position
        else:
            angle = position
        print("ANGLE:", angle)
        
        # Pixel offset coefficient (depends on screen scale, here for 125%)
        point_stop = angle * 1.12  

        # 5. Emulate slider dragging using PyAutoGUI
        arr = sb.find_element(By.CLASS_NAME, 'verify-bar-area')
        arr_location = arr.location
        
        # Disconnect Selenium so PyAutoGUI can control the mouse without conflicts
        sb.disconnect()
        
        # Calculate slider coordinates on screen
        x = arr_location['x'] + 150  # Adapted for 125% scale
        y = arr_location['y'] + 190  # Adapted for 125% scale

        # Physical mouse movement and dragging
        pyautogui.moveTo(x, y, duration=random.uniform(0.2, 1.2))
        pyautogui.mouseDown(x, y)
        pyautogui.moveTo(x + point_stop - 20, y + random.randint(-5, 5), duration=random.uniform(0.3, 1.9))
        pyautogui.moveTo(x + point_stop, y + random.randint(-5, 5), duration=random.uniform(0.9, 2.1))
        pyautogui.mouseUp()
        
        # Move mouse to a random place to simulate human behavior
        pyautogui.moveTo(random.randint(750, 1200), random.randint(450, 650), duration=random.uniform(0.9, 2.1))
        time.sleep(5)
        
        # Return control to Selenium
        sb.connect()
        
    except Exception as e:
        print(e)

Response processing and angle calculation

In a successful API response, the request field contains not only the base angle, but also the center and point_circle coordinate arrays.

Sites with Rotate Slider often require rotation in a strictly defined direction. The logic provided in the code (if (center_x <= 161 ...) analyzes the fragment position relative to the center and determines whether to subtract the angle from 360 degrees to rotate the slider in the correct direction.

Why use PyAutoGUI instead of Selenium ActionChains?

Standard Selenium methods for dragging elements are often detected by anti-bot systems when interacting with canvas. The pyautogui library controls the physical mouse at the operating system level, making the actions indistinguishable from a real user.

Important nuances of using PyAutoGUI:

  1. The browser must be run in visible mode (headless=False).
  2. Screen scaling (DPI) must be taken into account. In the provided code, the coefficients (point_stop = angle * 1.12 and x, y offsets) are calculated for 125% Windows scaling. If you have 100% or 150%, these values will need to be adapted.
  3. During PyAutoGUI operation, Selenium control is disconnected (sb.disconnect()) to avoid focus and coordinate conflicts.

Reports on solution correctness

If the site rejected the solution, be sure to report it via the reportIncorrect method. This helps the service improve its algorithms and refunds your funds. If the solution successfully passed verification, send reportCorrect.

python Copy
import requests

API_KEY = "YOUR_API_KEY"
TASK_ID = "123456789"

# Report incorrect solution
requests.post(
    "https://api.2captcha.com/reportIncorrect",
    json={"clientKey": API_KEY, "taskId": TASK_ID}
)

# Report correct solution
requests.post(
    "https://api.2captcha.com/reportCorrect",
    json={"clientKey": API_KEY, "taskId": TASK_ID}
)

Detailed guide on submitting reports: https://2captcha.com/h/how-to-submit-reports

Common errors and solutions

Error / Problem Cause Solution
Slider moves to the wrong place Coordinates are miscalculated due to screen scale (DPI). Adapt the point_stop multipliers and x, y offsets to your current screen scale (100%, 125%, 150%).
ERROR_IMAGE_TYPE_NOT_SUPPORTED The data:image/png;base64, prefix was not removed. Ensure you use .replace('data:image/png;base64,', '') before sending to the API.
PyAutoGUI does not click the slider Conflict between Selenium and the system mouse. Ensure you call sb.disconnect() before starting PyAutoGUI and sb.connect() afterwards.
Error finding canvas The site updated its layout or the captcha has not loaded yet. Increase time.sleep() before extracting the canvas or use explicit waits for element appearance.