首页 > Python基础教程 >
-
爬虫(十二):图形验证码的识别、滑动验证码的识
1. 验证码识别
随着爬虫的发展,越来越多的网站开始采用各种各样的措施来反爬虫,其中一个措施便是使用验证码。随着技术的发展,验证码也越来越花里胡哨的了。最开始就是几个数字随机组成的图像验证码,后来加入了英文字母和混淆曲线,或者是人眼都很难识别的数字字母。很多国内网站还出现了中文字符的验证码,使得识别越发困难。
然后又出现了需要我们识别文字,点击与文字相符合的图片,验证码完全正确,验证才能通过。下载的这种交互式验证码越来越多了,如滑动验证码需要滑动拼合滑块才能完成验证,点触验证码需要完全点击正确结果才可以完成验证,另外还有滑动宫格验证码、计算题验证码等。
最让我生气的就是外国的一款邮箱的验证码,freemail邮箱的验证码,随机生成一些图片,让你点击符合标题的图片,这种别说爬虫了,对人为操作都不友好。(满满的怨念)
还有一种外国邮箱tutanota,是一个时钟验证码,我们想要根据上面的时间指针来输入正确的时间。但是被我们公司的大佬自己写的OCR识别出来了,虽然错误率还很高,但是这是一个大的突破。
验证码变得越来越复杂,爬虫的工作也变得愈发艰难,有时候我们必须通过验证码的验证才可以访问页面,本章就专门针对简单的验证码的识别做大概的讲解(难的我也不会)。
1.1 使用百度OCR
tesserocr是很早的一款OCR文字识别技术了,算是过时的东西了。百度OCR中文字识别每天都有限制次数的免费额度,所以我们就用它了(别问,问就是白嫖)。
百度搜索百度ocr,进入官网。
往下翻,直到翻到下图界面。
登录即可,没有账号就注册。
登录成功后,创建应用。
中间内容填的合理就行。
这些内容不能给大家看了,下面的代码中,我会将之用********替换,各位只要根据自己的百度平台的内容修改下即可。
1.2 图形验证码的识别
我们首先识别最简单的以种验证码,即图形验证码。这种验证码最早出现,现在也很常见,一般由4位字母或者数字组成。例如,中国知网的注册页面有类似的验证码,链接为http://my.cnki.net/Register/CommonRegister.aspx。
表单的最后一项就是图形验证码,我们必须完全正确输入图中的字符才可以完成注册。
为了便于实验,我们先将验证码的图片保存到本地。
打开开发者工具,找到验证码元素。验证码元素是一张图片,它的src属性是heckCode.aspx。我们直接打开这个链接即:http://my.cnki.net/Register/CheckCode.aspx ,就可以看到个验证码,右键保存即可将其命名为code.jpg。
这样我们就可以得到一张验证码图片,以供测试识别使用。
接下来新建一个项目,将验证码图片放到项目根目录下,用百度ocr识别该验证码。
- from aip import AipOcr
- import codecs# pip install baidu-aip
- #读取图片函数
- def ocr(path):
- with open(path,'rb') as f:
- return f.read()
- def main():
- filename = "code.jpg"
- print("已经收到,正在处理,请稍后....")
- app_id = '*********'
- api_key = '********************'
- secret_key = '*******************************'
- client = AipOcr(app_id,api_key,secret_key)
- #读取图片
- image = ocr(filename)
- #进程OCR识别
- dict1 = client.general(image)
- #print(dict1)
- with codecs.open(filename + ".txt","w","utf-8") as f:
- for i in dict1["words_result"]:
- f.write(str(i["words"] + "\r\n"))
- print ("处理完成")
- if __name__ == '__main__':
- main()
结果:
结果差强人意,可能是由于验证码内的多余线条干扰了图片的识别。
对于这种情况,我们还需要做一下额外的处理,如转灰度、二值化等操作。
这就需要我们使用到一个新的模块PIL了,我们这里先用,以后我特意出一章关于这个模块的使用。
pip install pillow -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com Looking in indexes: http://pypi.douban.com/simple/
别问为什么安装的是pillow模块,而不是PIL模块,到时候会说明的。
我们可以利用Image对象的convert()方法参数传入L,即可将图片转化为灰度图像。
- image = image.convert('L')
- image.show()
传入1即可将图片进行二值化处理。
我们还可以指定二值化的阔值 上面的方法采用的是默认阔值 127 不过我们不能直接转化原因, 要将原图先转为灰度图像,然后再指定二值化阔值。
- from aip import AipOcr
- import codecsfrom PIL import Image
- #读取图片函数
- def ocr(path):
- with open(path,'rb') as f:
- return f.read()
- def main():
- print("已经收到,正在处理,请稍后....")
- app_id = '**********'
- api_key = '************************'
- secret_key = '***************************'
- client = AipOcr(app_id,api_key,secret_key)
- #读取图片
- image = Image.open('code.jpg')
- image = image.convert('L')
- threshold = 110
- table = []
- for i in range(256):
- if i < threshold:
- table.append(0)
- else:
- table.append(1)
- image = image.point(table,'1')
- image.save("code.png",'png')
- #读取PIL处理后保存图片函数
- image = ocr('