You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python+Selenium结合2captcha API解决ReCaptcha V2点击验证码的两类问题?

解决ReCaptcha V2图片点击验证的两个核心问题

我来帮你搞定这两个问题,直接上解决方案和修改后的代码:

一、生成随机命名截图并压缩至100KB以下

要实现这个需求,我们可以结合uuid生成唯一文件名,再用PIL调整图片质量来压缩大小:

  • 随机命名:用uuid.uuid4()生成不重复的文件名,避免多次运行时覆盖旧截图
  • 图片压缩:通过PIL的Image.save()方法调整quality参数,循环尝试直到文件大小低于100KB(也可以直接设置一个合适的初始值,比如60-70,根据实际情况调整)

二、解析坐标模拟点击&验证后删除截图

对于2captcha返回的坐标格式,我们需要先解析出每个点的x/y值,再用Selenium的ActionChains模拟点击;验证完成后用os.remove()删除截图:

  • 坐标解析:把返回的字符串按;分割,逐个提取x=xxx,y=yyy中的数值
  • 模拟点击:需要先定位到验证码图片的元素,因为返回的坐标是相对于验证码图片的,不是整个页面的绝对坐标
  • 删除截图:添加异常处理,避免文件不存在时抛出错误

修改后的完整代码

from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from time import sleep, time
from PIL import Image
import requests
import uuid
import os

# 生成随机文件名
def get_random_filename():
    return f"{uuid.uuid4()}.jpg"

# 压缩图片至指定大小以下(单位:KB)
def compress_image(input_path, output_path, max_size_kb=100):
    quality = 80  # 初始质量
    while True:
        with Image.open(input_path) as img:
            img.save(output_path, "JPEG", quality=quality, optimize=True)
        file_size = os.path.getsize(output_path) / 1024  # 转成KB
        if file_size <= max_size_kb or quality <= 10:
            break
        quality -= 5  # 每次降低5%质量
    return output_path

# 打开注册页面
browser = webdriver.Chrome('D:\\chromedriver')
browser.get('http://testing-ground.scraping.pro/recaptcha')
browser.maximize_window()

# 点击复选框
recaptcha_checkbox = browser.find_element_by_xpath("//*[@role='presentation']")
sleep(3)
recaptcha_checkbox.click()
sleep(3)

# 生成随机截图并压缩
temp_screenshot = get_random_filename()
browser.get_screenshot_as_file(temp_screenshot)
compressed_screenshot = compress_image(temp_screenshot, temp_screenshot)  # 覆盖原文件

# 发送POST请求到2captcha
api_key = "你的2captcha密钥"
url = 'http://2captcha.com/in.php'
files = {'file': open(compressed_screenshot, 'rb')}
data = {
    'key': api_key,
    'method': 'post',
    'coordinatescaptcha': '1',
    'textinstructions': 'click on fire hydrant'
}
resp = requests.post(url, files=files, data=data)
if resp.ok:
    captcha_id = resp.text[3:]
    print(f"验证码ID:{captcha_id}")

# 轮询获取验证结果
fetch_url = f"http://2captcha.com/res.php?key={api_key}&action=get&id={captcha_id}"
captcha_result = None
for i in range(1, 10):
    sleep(5)  # 等待5秒
    resp = requests.get(fetch_url)
    if resp.text.startswith('OK|'):
        captcha_result = resp.text[3:]
        break

if captcha_result:
    print(f"验证结果:{captcha_result}")
    # 定位验证码图片元素(需要根据实际页面调整定位方式)
    captcha_image = browser.find_element_by_xpath("//div[@class='rc-image-tile-wrapper']")
    # 解析坐标
    coordinates = captcha_result.split(';')
    actions = ActionChains(browser)
    for coord in coordinates:
        if coord.strip():
            x_str, y_str = coord.split(',')
            x = int(x_str.split('=')[1])
            y = int(y_str.split('=')[1])
            # 相对于验证码图片点击
            actions.move_to_element_with_offset(captcha_image, x, y).click().perform()
            sleep(0.5)  # 每次点击间隔0.5秒,模拟真人操作
    # 等待验证完成
    sleep(3)
else:
    print("验证码验证超时或失败")

# 清理截图文件
try:
    if os.path.exists(temp_screenshot):
        os.remove(temp_screenshot)
        print("截图已删除")
except Exception as e:
    print(f"删除截图失败:{str(e)}")

# 关闭浏览器(可选)
browser.quit()

关键细节说明

  1. 随机文件名:用uuid保证每次运行生成的文件名唯一,不会和之前的截图冲突
  2. 图片压缩:循环调整质量参数,确保最终文件大小低于100KB,符合2captcha的要求
  3. 坐标点击:必须基于验证码图片元素的相对坐标,否则点击位置会偏移(如果页面有滚动,还要先滚动到验证码可见区域)
  4. 截图清理:添加try-except处理,避免文件已被删除或权限问题导致报错

内容的提问来源于stack exchange,提问作者Saeed Alipoor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:21:50