VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 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识别该验证码。


  1. from aip import AipOcr
  2. import codecs# pip install baidu-aip
  3.  
  4. #读取图片函数
  5. def ocr(path):
  6. with open(path,'rb') as f:
  7. return f.read()
  8. def main():
  9. filename = "code.jpg"
  10. print("已经收到,正在处理,请稍后....")
  11. app_id = '*********'
  12. api_key = '********************'
  13. secret_key = '*******************************'
  14. client = AipOcr(app_id,api_key,secret_key)
  15.   #读取图片
  16. image = ocr(filename)
  17.   #进程OCR识别
  18. dict1 = client.general(image)
  19.   #print(dict1)
  20. with codecs.open(filename + ".txt","w","utf-8") as f:
  21. for i in dict1["words_result"]:
  22. f.write(str(i["words"] + "\r\n"))
  23. print ("处理完成")
  24. if __name__ == '__main__':
  25. 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,即可将图片转化为灰度图像。 


  1. image = image.convert('L')
  2. image.show()

传入1即可将图片进行二值化处理。

我们还可以指定二值化的阔值 上面的方法采用的是默认阔值 127 不过我们不能直接转化原因, 要将原图先转为灰度图像,然后再指定二值化阔值。 


  1. from aip import AipOcr
  2. import codecsfrom PIL import Image
  3.  
  4. #读取图片函数
  5. def ocr(path):
  6. with open(path,'rb') as f:
  7. return f.read()
  8. def main():
  9. print("已经收到,正在处理,请稍后....")
  10. app_id = '**********'
  11. api_key = '************************'
  12. secret_key = '***************************'
  13. client = AipOcr(app_id,api_key,secret_key)
  14. #读取图片
  15. image = Image.open('code.jpg')
  16. image = image.convert('L')
  17. threshold = 110
  18. table = []
  19. for i in range(256):
  20. if i < threshold:
  21. table.append(0)
  22. else:
  23. table.append(1)
  24. image = image.point(table,'1')
  25. image.save("code.png",'png')
  26. #读取PIL处理后保存图片函数
  27. image = ocr('