选择某种颜色字母的验证码破解方法

现在有不少网站的验证码都变成了“请输入验证码图片中蓝色文字”这种形式,如下图

大部分打码平台并不支持这种形式,所以得自己手动做些处理,

基本思想:

划归,即把这种验证码图片处理成打码平台可以打码的样子。

首先,看下页面元素

 发现这个图片是转码成base64的一张png图片,所以,

第一步,把这个base64字符串及需要的颜色抓出来

def get_base64str_color(driver):
    """
    获取图片验证码的base64字符串你及需要识别的颜色
    :param driver:
    :return:
    """
    base64_str = ""
    color = ""
    for i in range(5):    # 因为这个网站的验证码不稳定,且需要过滤黄色,限制最多刷5次
        base64_str = driver.find_element_by_id("yzm_img").get_attribute("src")
        if base64_str == NO_VERIFICATION_CODE_SRC:
            try:
                driver.find_element_by_id("yzm_img").click()
                time.sleep(2)
            except:
                pass
            continue
        try:
            color = driver.find_element_by_id("yzminfo").find_element_by_tag_name("font").get_attribute("color")
        except:
            color = ""
        if color == "yellow": # 由于黄色识别率比较低,所以出现黄色需要再刷一下
            driver.find_element_by_id("yzm_img").click()
            time.sleep(1)
            continue
        else:
            break
    return color, base64_str

第二步,将base64字符串转换成图片

def base64_to_image(base64_str, color):
    """
    将base64字符串转换成图片
    :param base64_str:
    :param color:
    :return:
    """
    base64_data = re.sub('^data:image/.+;base64,', '', base64_str)
    byte_data = base64.b64decode(base64_data)
    image_data = BytesIO(byte_data)
    img = Image.open(image_data)
    img = img.convert("RGB")
    return sectional_by_color(img, color)

第三步,把需要识别的字符转换成黑色,其他颜色都转换成白色,即生成黑白图

def sectional_by_color(img, color):
    """
    把需要识别的字符转换成黑色,其他颜色都转换成白色
    :param img:
    :param color:
    :return:
    """
    pixdata = img.load()
    for y in range(img.size[1]):
        for x in range(img.size[0]):
            pix = pixdata[x, y]
            if color == "red":   # 255, 0, 0
                if pix[0] >= 128 and pix[1] < 128 and pix[2] < 128:
                    pixdata[x, y] = (0, 0, 0)
                else:
                    pixdata[x, y] = (255, 255, 255)
            elif color == "yellow":  # 255, 255, 0
                if pix[0] > 128 and pix[1] > 128 and pix[2] < 128:
                    pixdata[x, y] = (0, 0, 0)
                else:
                    pixdata[x, y] = (255, 255, 255)
            elif color == "blue":   # 0, 0, 255
                if pix[0] < 128 and pix[1] < 128 and pix[2] > 128:
                    pixdata[x, y] = (0, 0, 0)
                else:
                    pixdata[x, y] = (255, 255, 255)
            else:   # 0, 0, 0
                if pix[0] < 128 and pix[1] < 128 and pix[2] < 128:
                    pixdata[x, y] = (0, 0, 0)
                else:
                    pixdata[x, y] = (255, 255, 255)
    return img

第四步,把生成的黑白图扔给第三方打码平台进行打码

def get_pic_code(base64_str, color):
    """
    打码
    :param base64_str:
    :param color:
    :return:
    """
    img = base64_to_image(color, base64_str)
    rc = RClient(RK_USERNAME, RK_PASSWORD, RK_SOFT_ID, RK_SOFT_KEY)
    fp = BytesIO()
    img.convert('RGB').save(fp, Image.registered_extensions()[".png"])
    return rc.rk_create(fp.getvalue(), 5000)["Result"]

连着测了10次,都打码成功了

猜你喜欢

转载自blog.csdn.net/fuhtead/article/details/87969336