抖音最近升级了验证码,之前都是跳滑块,最近开始跳文字点选验证了,我这里就用selenium搞一下自动化,识别库使用了ddddocr。
一、目标文字识别
从上图可以看出,有两部分文字需要识别,我们先识别目标文字,也就是上面的“斯”、”慷“。
首先通过xpath先提取出图片url并下载。
image2 = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="verify-bar-code"]')))
target_img_url = image2.get_attribute('src')
target_image_content = requests.get(target_img_url).content
然后通过ddddocr库的ocr功能直接识别出文字。
docr = ddddocr.DdddOcr(show_ad=False)
target_words = docr.classification(target_image_content)
二、背景图文字识别
同样先通过xpath提出背景图片url并下载。
image1 = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="captcha-verify-image"]')))
background_img_url = image1.get_attribute('src')
background_image_content = requests.get(background_img_url).content
获取图片后,直接使用ddddocr库的目标检测函数识别背景图文字坐标。
ddet = ddddocr.DdddOcr(det=True, show_ad=False)
poses = ddet.detection(background_image_content)
然后通过识别出来的坐标对背景图的每个文字分别进行裁剪,裁剪后对图片进行文字的ocr识别。
img = Image.open(BytesIO(background_image_content))
draw = ImageDraw.Draw(img)
click_identify_result = {}
for row in poses:
# 框字
row = (row[0] - 3, row[1] - 3, row[2] + 3, row[3] + 3)
x1, y1, x2, y2 = row
draw.line(([(x1, y1), (x1, y2), (x2, y2), (x2, y1), (x1, y1)]), width=1, fill='red')
# 裁剪出单个字
corp = img.crop(row)
img_byte = BytesIO()
corp.save(img_byte, 'png')
# 识别出单个字
word = docr.classification(img_byte.getvalue())
click_identify_result[word] = row
img.show()
三、计算点击坐标并点击
文字全部识别完毕后,只要计算下点击坐标就好了,这里我直接放代码吧。
# 计算文字点击坐标
img_xy = {}
for key, xy in click_identify_result.items():
if key:
img_xy[key] = (int((xy[0] + xy[2]) / 2), int((xy[1] + xy[3]) / 2))
logger.info(img_xy)
# 计算最终点击顺序与坐标
result = {}
for word in target_words:
result[word] = img_xy[word]
logger.info(result)
# 点击坐标
image1_x = image1.location.get('x')
image1_y = image1.location.get('y')
for xy in result.values():
x = xy[0] * (340 / 552)
y = xy[1] * (212 / 344)
ActionChains(browser).reset_actions()
ActionChains(browser).move_by_offset(image1_x + x, image1_y + y).click().perform()
PS:计算坐标的时候要记得缩放下。
最终效果如下:
PS:后面实际跑下来,识别的准确性比较一般,后续可以考虑使用别的识别库或者自己训练模型。
正文完