最近在学习爬虫,碰到很多验证登录,今天分享一个点选文字验证码识别以及我在使用的验证码识别平台。(上篇文章有涉及滑块验证)
首先,注册一个超级鹰账号,选择充值0.5-1元即可。
进入用户中心 > 软件ID 生成一个用来接入接口的软件ID,下载示例代码,然后就可以在pycharm中使用。超级鹰可以识别多种类型,b站验证码属于‘9004’
以b站验证码为例:
具体方法:首先模拟登录b站,进行登录,然后对验证码图片进行截图,使用screenshot()函数,将保存的图片传递给第三方平台识别,返回文字的坐标,模拟点击图片中的文字,等待验证成功。
具体实现:
1.模拟登录,对出现的验证码图片截图,定位后直接.screenshot('路径加名称')
from selenium import webdriverfrom selenium.webdriver.chrome.service import Services=Service("chromedriver.exe")browser=webdriver.Chrome(service=s)from mon.by import Byimport timefrom selenium.webdriver import ActionChainsbrowser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})browser.get('/')browser.maximize_window()time.sleep(1)browser.find_element(By.XPATH,'//*[@id="i_cecream"]/div[1]/div[1]/ul[2]/li[1]/li/div/div/span').click()time.sleep(1)browser.find_element(By.XPATH,'/html/body/div[3]/div/div[2]/div[3]/div[2]/div[1]/input').send_keys('账号')time.sleep(1)browser.find_element(By.XPATH,'/html/body/div[3]/div/div[2]/div[3]/div[2]/div[2]/div[1]/input').send_keys('密码')time.sleep(1)browser.find_element(By.XPATH,'/html/body/div[3]/div/div[2]/div[3]/div[3]/div[2]').click()time.sleep(1)#验证码图片截取,首先对他定位bz_png=browser.find_element(By.XPATH,'/html/body/div[4]/div[2]/div[6]/div/div')bz_png.screenshot('./bz.png') 截图
2.将保存的图片使用第三方平台识别,并返回坐标值
#超级鹰示例代码#!/usr/bin/env python# coding:utf-8import requestsfrom hashlib import md5class Chaojiying_Client(object):def __init__(self, username, password, soft_id):self.username = usernamepassword = password.encode('utf8')self.password = md5(password).hexdigest()self.soft_id = soft_idself.base_params = {'user': self.username,'pass2': self.password,'softid': self.soft_id,}self.headers = {'Connection': 'Keep-Alive','User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',}def PostPic(self, im, codetype):"""im: 图片字节codetype: 题目类型 参考 /price.html"""params = {'codetype': codetype,}params.update(self.base_params)files = {'userfile': ('ccc.jpg', im)}r = requests.post('/Upload/Processing.php', data=params, files=files, headers=self.headers)return r.json()def ReportError(self, im_id):"""im_id:报错题目的图片ID"""params = {'id': im_id,}params.update(self.base_params)r = requests.post('/Upload/ReportError.php', data=params, headers=self.headers)return r.json()chaojiying = Chaojiying_Client('账号', '密码', '软件ID')#用户中心>>软件ID 生成一个替换 96001im = open('./bz.png', 'rb').read()print(chaojiying.PostPic(im, 9004))#验证码类型 9004##############识别结果:{'err_no': 0, 'err_str': 'OK', 'pic_id': '117282113500107', 'pic_str': '99,71|58,124', 'md5': 'dabef9f9c5e6d3141f3b89d273947df6'}#chaojiying.PostPic(im, 9004)['pic_str']即为坐标的值,因为每次验证码都不一样,这次只有两个文字,只返回两个坐标 '99,71|58,124'
由于返回的坐标值中有|,我们进一步解析,使用split()函数。
result=chaojiying.PostPic(im, 9004)['pic_str']all_list = [] # 要存储即将被点击的点的坐标 [[x1,y1],[x2,y2]]list_1 = result.split('|')count_1 = len(list_1)for i in range(count_1):xy_list = []x = int(list_1[i].split(',')[0])y = int(list_1[i].split(',')[1])xy_list.append(x)xy_list.append(y)all_list.append(xy_list)#############print(all_list)就可以得到:[[218, 161], [185, 239], [24, 215], [117, 148]]这样的一个列表
3.拿到坐标值后进行模拟点击
for l in all_list:x = l[0]y = l[1]ActionChains(browser).move_to_element_with_offset(bz_png, x, y).click().perform()time.sleep(0.5)#move_to_element_with_offset(to_element, xoffset, yoffset) 移动到距离某个元素(左上角坐标)多少距离的位置
模拟点击成功
同类型的验证码都可以这样识别,最后我发现用手机号登录b站还要进行手机短信验证码验证,所以说无法用手机号模拟登陆,本文目的也只是针对此类验证码进行一个识别。