Files
atomk-hermes-skills/skills/archived/drissionpage-auto-login/SKILL.md
T

5.1 KiB

name, description, tags
name description tags
drissionpage-auto-login Automate login with DrissionPage — discover login pages, fill forms, solve CAPTCHAs with ddddocr, and verify success.
drissionpage
automation
login
captcha
ddddocr
web-scraping

DrissionPage Auto-Login with CAPTCHA Solving

Automate login to web applications using DrissionPage, with automatic CAPTCHA solving via ddddocr.

Setup

python3 -m venv /tmp/drission_env && source /tmp/drission_env/bin/activate
pip install DrissionPage ddddocr

Browser Configuration

from DrissionPage import ChromiumPage, ChromiumOptions
import ddddocr
import os
import time

co = ChromiumOptions()
co.set_browser_path('/home/ubuntu/.cache/ms-playwright/chromium-1217/chrome-linux64/chrome')
co.set_argument('--no-sandbox')
co.set_argument('--disable-dev-shm-usage')
co.set_argument('--disable-gpu')
co.headless()
co.auto_port()
page = ChromiumPage(co)

Login Discovery Workflow

When the login URL is unknown:

  1. Visit the homepage and scan for login links:
page.get('https://www.example.com')
time.sleep(3)

links = page.eles('tag:a')
for link in links:
    href = link.attr('href') or ''
    text = link.text.strip()
    if 'login' in href.lower() or 'login' in text.lower() or '登录' in text:
        print(f"Found: {text} -> {href}")
  1. Common login URL patterns to try:
    • /login, /signin, /auth
    • login.example.com, passport.example.com, account.example.com

Form Filling

# Find inputs by name, placeholder, or type
inputs = page.eles('css:input')
for inp in inputs:
    itype = inp.attr('type') or 'text'
    name = inp.attr('name') or ''
    ph = inp.attr('placeholder') or ''
    
    if itype in ['text', 'email']:
        # Heuristic: match common username field indicators
        if any(kw in (name + ph).lower() for kw in ['phone', 'email', 'account', 'user', 'mobile', 'login']):
            inp.clear().input('your_username')
    elif itype == 'password':
        inp.clear().input('your_password')

CAPTCHA Solving with ddddocr

# 1. Find the CAPTCHA image element
captcha_img = (page.ele('css:img.captcha') 
            or page.ele('css:.captcha-img') 
            or page.ele('xpath://img[contains(@src, "captcha")]'))

if not captcha_img:
    captcha_input = page.ele('@name=captcha')
    if captcha_input:
        captcha_img = captcha_input.sibling('tag:img')

# 2. Save the image (PITFALL: use a simple filename, NOT a directory path)
# DrissionPage's save() may create a directory if the src URL looks like a path.
# Always use a clean local filename.
import shutil
captcha_path = '/tmp/captcha_solve.jpg'
if os.path.isdir(captcha_path):
    shutil.rmtree(captcha_path)

# Use screenshot method instead of save() for reliability:
captcha_img.get_screenshot(path=captcha_path)

# 3. OCR recognition
ocr = ddddocr.DdddOcr()
with open(captcha_path, 'rb') as f:
    img_bytes = f.read()
captcha_text = ocr.classification(img_bytes)
print(f"CAPTCHA: {captcha_text}")

# 4. Fill the captcha field
page.ele('@name=captcha').clear().input(captcha_text)

Submit and Verify

# Click login button
login_btn = page.ele('text:登录') or page.ele('text:Login') or page.ele('css:button[type=submit]')
if login_btn:
    login_btn.click()
else:
    page.press('Enter')

time.sleep(5)

# Verify success
if 'dashboard' in page.url.lower() or 'main' in page.url.lower():
    print("Login successful!")
else:
    # Check for error messages
    body = page('tag:body').text
    if 'error' in body.lower() or '错误' in body:
        print("Login failed — check credentials or captcha")

Retry with CAPTCHA Refresh

If the captcha is wrong, refresh and retry:

for attempt in range(3):
    # ... fill form and solve captcha ...
    login_btn.click()
    time.sleep(3)
    
    if 'error' not in page('tag:body').text.lower():
        break
    
    # Click captcha image to refresh
    if captcha_img:
        captcha_img.click()
        time.sleep(1)
    else:
        page.refresh()
        time.sleep(2)

Pitfalls

  • save() creates directories: DrissionPage's element.save(path) may create a directory if the source URL contains path-like segments (e.g., captcha.jpg;jsessionid=...). Always use a clean local filename and check os.path.isdir() first.
  • get_screenshot() is more reliable: For single elements, element.get_screenshot(path=...) is more reliable than save().
  • uv-managed Python: Use a temp venv to install packages.
  • Headless + sandbox flags: Always use --no-sandbox --disable-dev-shm-usage --disable-gpu and co.headless().
  • Auto port: Use co.auto_port() to avoid conflicts.
  • Wait times: Add time.sleep(2-5) after page loads and form submissions for JS-rendered content.
  • Iframe logins: If inputs are inside iframes, switch context: page = page.eles('tag:iframe')[0].child().
  • Multiple hidden inputs: Sites may have many hidden inputs. Filter by type and visible attributes.
  • CAPTCHA case sensitivity: Some sites require uppercase/lowercase matching. Try captcha_text.upper() or .lower() if login fails.