最新验证码识别模拟登陆B站

「本文目录」

  • 1 分析登录界面结构
  • 2 使用selenium打开登录页面
  • 3 获取页面当前验证码图片
  • 4 使用超级鹰识别验证码
  • 5 对获取的坐标数据进行提取,并用动作链完成点击

picture.image

1 分析登录界面结构

picture.image

首先明确我们的目标,打开登陆界面,定位用户名和密码对应的标签,输入相关数据后,点击登录,此时页面会弹出验证码。

picture.image

下面用两种方法进行验证码的获取,然后提交给**「超级鹰」** 进行识别,接收到汉字的坐标后,处理数据,然后用动作链进行点击操作,最后定位点击确认,登陆成功。

2 使用selenium打开登录页面

「代码实现:」


        
# 使用selenium打开登录界面  
bro = webdriver.Chrome(executable_path='./chromedriver')  
bro.get('https://passport.bilibili.com/login')  
  
# 定位用户名,密码输入框  
username = bro.find_element_by_id('login-username')  
password = bro.find_element_by_id('login-passwd')  
  
sleep(1)  
# 将自己的用户名密码替换xxxxxx  
username.send_keys('xxxxxx')  
sleep(1)  
password.send_keys('xxxxxx')  
sleep(1)  
  
# 定位登录按钮并点击  
bro.find_element_by_xpath('//*[@id="geetest-wrap"]/div/div[5]/a[1]').click()  
sleep(2)  

    

3 获取页面当前验证码图片

3.1 方法一:页面截图,将验证码区域进行裁剪保存

使用此方法时,注意我们截取验证码图片时需要 截取完整 ,完整验证码截图如下:

picture.image

首先做的当然是将点击登录后的页面进行 截图 ,然后 定位 到验证码的位置,通过 location() 方法获取验证码左上角的坐标, size() 获取验证码的宽和高,左上角坐标加上宽和高就是验证码右下角的坐标。获取坐标后就可以用 crop() 方法来进行裁剪,然后将裁剪到的验证码图片保存。

此时虽然获取了验证码图片,但是还不能直接提交给超级鹰。

因为超级鹰识别的验证码图片的 宽和高有限制 ,最好不超过 460px*310px

但是截取到的验证码图片宽高为 338px*432px ,这时就要先将图片缩小一倍再提交即可,等到收到坐标数据再将 坐标乘2

「代码实现:」


        
# 本文相关完整代码可以关注微信公众号:简说Python,回复:B站 获取。  
# save\_screenshot就是将当前页面进行截图且保存  
bro.save_screenshot('page.png')  
  
# 定位验证码图片的位置  
code_img_ele = bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[6]/div/div')  
location = code_img_ele.location  # 验证码左上角的坐标x,y  
size = code_img_ele.size  # 验证码图片对应的长和宽  
  
# 左上角和右下角的坐标  
# 这里坐标乘1.25是由于电脑屏幕的比例不是100%,我的是125%,请自行在设置中查看  
rangle = (  
    int(location['x'] * 1.25), int(location['y'] * 1.25), int((location['x'] + size['width']) * 1.25),  
    int((location['y'] + size['height']) * 1.25)  
)  
  
i = Image.open('./page.png')  
code_img_name = './code.png'  
# crop根据rangle元组内的坐标进行裁剪  
frame = i.crop(rangle)  
frame.save(code_img_name)  
  
# 缩小图片,宽为169,高为216  
code = Image.open('./code.png')  
small_img = code.resize((169, 216))  
small_img.save('./small\_img.png')  
print(code.size, small_img.size)  

    

3.2方法二、通过网页获取图片地址,并保存

这种方法比上一种更加方便,分析网页源码获取图片地址,对该地址发送请求,接收返回的二进制文件,进行保存。首先打开网页源码找到图片地址。

picture.image

图片地址是img标签的src属性值,通过xpath得到地址,直接对此url发送请求,接收数据并保存即可。

「注意:」 由于获取的图片的高度仍然大于超级鹰标准格式,所以也需要将图片缩小。

「代码实现:」


        
# 本文相关完整代码可以关注微信公众号:简说Python,回复:B站 获取。  
# 获取img标签的src属性值  
img_url = bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[6]/div/div/div[2]/div[1]/div/div[2]/img').get_attribute('src')  
headers = {  
    'Users-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36'  
}  
# 获取图片二进制数据  
img_data = requests.get(url=img_url, headers=headers).content  
with open('./node1.png', 'wb')as fp:  
    fp.write(img_data)  
i = Image.open('./node1.png')  
# 将图片缩小并保存,设置宽为172,高为192  
small_img = i.resize((172, 192))  
small_img.save('./small\_img1.png')  

    

4 使用超级鹰识别验证码

这部分没什么说的,直接调用就行。

「代码如下:」


        
# 本文相关完整代码可以关注微信公众号:简说Python,回复:B站 获取。  
# 将验证码提交给超级鹰进行识别  
chaojiying = Chaojiying_Client('用户名', '密码', '96001')  # 用户中心>>软件ID 生成一个替换 96001  
im = open('small\_img.png', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//  
# 9004是验证码类型  
print(chaojiying.PostPic(im, 9004)['pic\_str'])  
result = chaojiying.PostPic(im, 9004)['pic\_str']  

    

5 对获取的坐标数据进行提取,并用动作链完成点击

超级鹰识别返回的数据格式是:123,12 | 234,21。
我们可以将数据以' | '进行分割,保存到列表中,再以逗号分割将x,y的坐标保存,得到[ [123,12],[234,21] ]这一格式,然后遍历这一列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作,最后定位并点击确认,登录成功。

「代码实现:」


        
# 本文相关完整代码可以关注微信公众号:简说Python,回复:B站 获取。  
all_list = []  # 要存储即将被点击的点的坐标  [[x1,y1],[x2,y2]]  
if '|' in result:  
    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)  
else:  
    x = int(result.split(',')[0])  
    y = int(result.split(',')[1])  
    xy_list = []  
    xy_list.append(x)  
    xy_list.append(y)  
    all_list.append(xy_list)  
  
# 遍历列表,使用动作链对每一个列表元素对应的x,y指定的位置进行点击操作  
# x,y坐标乘2和0.8,是由于  
for l in all_list:  
    x = l[0] * 2 * 0.8  
    y = l[1] * 2 * 0.8  
    # 将点击操作的参照物移动到指定的模块,  
    # 若用方法二获取的验证码图片,要添加下面代码对code\_img\_ele赋值  
    # code\_img\_ele = bro.find\_element\_by\_xpath('/html/body/div[2]/div[2]/div[6]/div/div/div[2]/div[1]/div/div[2]/img')  
    ActionChains(bro).move_to_element_with_offset(code_img_ele, x, y).click().perform()  
    sleep(0.1)  
    print('点击已完成')  
  
# 完成动作链点击操作后,定位确认按钮并点击  
bro.find_element_by_xpath('/html/body/div[2]/div[2]/div[6]/div/div/div[3]/a').click()
    

更多阅读

2020 年最佳流行 Python 库 Top 10

2020 Python中文社区热门文章 Top 10

5分钟快速掌握 Python 定时任务框架

特别推荐

picture.image

picture.image

点击下方阅读原文加入 社区会员

0
0
0
0
评论
未登录
暂无评论