最近在学习爬虫,碰到很多验证登录,今天分享一个点选文字验证码识别以及我在使用的验证码识别平台。(上篇文章有涉及滑块验证)
首先,注册一个超级鹰账号,选择充值0.5-1元即可。
进入用户中心 > 软件ID 生成一个用来接入接口的软件ID,下载示例代码,然后就可以在pycharm中使用。超级鹰可以识别多种类型,b站验证码属于‘9004’
以b站验证码为例:
具体方法:首先模拟登录b站,进行登录,然后对验证码图片进行截图,使用screenshot()函数,将保存的图片传递给第三方平台识别,返回文字的坐标,模拟点击图片中的文字,等待验证成功。
具体实现:
1.模拟登录,对出现的验证码图片截图,定位后直接.screenshot(‘路径加名称’)
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
s=Service("chromedriver.exe")
browser=webdriver.Chrome(service=s)
from selenium.webdriver.common.by import By
import time
from selenium.webdriver import ActionChains
browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", {
"source": """
Object.defineProperty(navigator, 'webdriver', {
get: () => undefined
})
"""
})
browser.get('https://www.bilibili.com/')
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-8
import requests
from hashlib import md5
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.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: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/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('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
chaojiying = Chaojiying_Client('账号', '密码', '软件ID') #用户中心>>软件ID 生成一个替换 96001
im = open('./bz.png', 'rb').read()
print(chaojiying.PostPic(im, 9004))#验证码类型 9004
##############识别结果:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '1172822008113500107', '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站还要进行手机短信验证码验证,所以说无法用手机号模拟登陆,本文目的也只是针对此类验证码进行一个识别。
版权声明:本文为weixin_54824895原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。