现在有不少网站的验证码都变成了“请输入验证码图片中蓝色文字”这种形式,如下图
大部分打码平台并不支持这种形式,所以得自己手动做些处理,
基本思想:
划归,即把这种验证码图片处理成打码平台可以打码的样子。
首先,看下页面元素
发现这个图片是转码成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次,都打码成功了