爬取数据,自动化的验证码验证是绕不开的,当然,验证码的自动识别其实都是调用其他api,在这里把这几天学习遇到过的验证码识别总结一下
话不多说先上图
如图,这里的src获得的是经base64加密后的图片字符串,如下
src="https://img-blog.csdnimg.cn/2022010707433569853.png"
其中,在base64,后的是加密的字符串,我们把它解密就可以得到
会有很多乱码不过不影响,我们可以看出这其实就是png的文件格式的数据,也就代表我们刚才那张图片,我们可以用python自带的b64解密并将数据写入png格式的文件中,就能得到我们想要的验证码,接着再把验证码文件上传到识别验证码的api接口就行了,当然,也有的api可以直接接受base64加密后的图片字符串,比如超级鹰
只要提供了相关数据的接口,我们也就可以写出提交base64的方法函数
def PostBase64(self, b64, codetype):
"""
b64: 图片文件base64字符串
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
'file_base64': b64
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, headers=self.headers)
return r.json()
接下来的任务就简单了,我们只需要定位到浏览器中的验证码的位置就可以了,这里采用selenium进行定位,再用re截取加密部分的字符串,发送给api,得到对应验证码后再用sendkeys写入
from selenium import webdriver
driver = Chrome()
driver.get('验证码所在网址')
cjy = Chaojiying_Client('超级鹰帐号', '超级鹰密码', '超级鹰软件号') #这里的cjy是外部导入的连接超级鹰api的库
img = driver.find_element_by_class_name('getCaptcha').get_attribute('src') #获得src的内容
print(img)
b64 = re.findall(r'data:image/png;base64,(.*)', img)[0]#用正则截取加密字符串
print(b64)
dic = cjy.PostBase64(b64, 1902)#向超级鹰接口发送消息并接收返回数据
print(dic)
driver.find_element_by_id('imgCaptcha').send_keys(dic['pic_str'])#向网页的对应位置写入获得的验证码
【这里截取的是自动登录的部分代码,下篇上完整代码】
这种验证码就比较麻烦了,这类链接通常你再次点开得到的图片跟你浏览器中加载出来的原图片不一样,也就是说,我们通过定位得到src链接后,再打开链接,得到的并不是我们想要的验证码图片。只有用魔法才能打败魔法,我们也得换一种方式来获取验证码——截图。
先上一个案例,网址如下:
https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx
这里的这个验证码就是会不断变化的,所以截屏是一个不错的选择,代码如下:
browser = webdriver.Chrome()
url = "https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx"
browser.get(url)
browser.find_element_by_id('email').clear()
browser.find_element_by_id('pwd').clear()
browser.find_element_by_id('code').clear()
browser.find_element_by_id('email').send_keys('帐号')
browser.find_element_by_id('pwd').send_keys('密码')
browser.save_screenshot('printscreen.png') # 截屏
imgelement = browser.find_element_by_id('imgCode') # 定位验证码
location = imgelement.location # 获取验证码x,y坐标,会有所偏移,所以后续有对偏移量进行了部分修改
size = imgelement.size # 验证码高度、宽度
left = int(location['x'] + 105)
top = int(location['y'] + 53)
right = int(location['x'] + size['width'] + 113)
bottom = int(location['y'] + size['height'] + 60)
img = Image.open('printscreen.png').crop((left, top, right, bottom)) # 打开截图
img.save('ccc.png')#将截取到的验证码保存为图片
验证码主要还是要靠selenium来配合识别,所以还是要多学习学习selenium的相关知识