点选文字验证码识别

  • Post author:
  • Post category:其他


最近在学习爬虫,碰到很多验证登录,今天分享一个点选文字验证码识别以及我在使用的验证码识别平台。(上篇文章有涉及滑块验证)

首先,注册一个超级鹰账号,选择充值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 版权协议,转载请附上原文出处链接和本声明。