反反爬虫之图片验证码

1、引言

目前,很多网站为了防止爬虫爬取,登录时需要用户输入验证码 ,以识别是否是人为操作,从而规避爬虫等软件的爬取。

1.1 图片验证码:

验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。

1.2 图片验证码的作用:

防止恶意破解密码、刷票、论坛灌水、刷页。有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登录尝试,实际上使用验证码是现在很多网站通行的方式(比如招商银行的网上个人银行,百度社区),我们利用比较简易的方式实现了这个功能。虽然登录麻烦一点,但是对网友的密码安全来说这个功能还是很有必要,也很重要。

1.3 处理方案

手动输入(input): 这种方法仅限于登录一次就可持续使用的情况

图像识别引擎解析: 使用光学识别引擎处理图片中的数据,目前常用于图片数据提取,较少用于验证码处理

打码平台: 爬虫常用的验证码解决方案

2、OCR 识别

OCR(Optical Character Recognition)是指使用扫描仪或数码相机对文本资料进行扫描成图像文件,然后对图像文件进行分析处理,自动识别获取文字信息及版面信息的软件。

在读取和处理图像、图像相关的机器学习以及创建图像等任务中,Python 一直都是非常出色的语言。虽然有很多库可以进行图像处理,但在这里我们只重点介绍:Tesseract

Tesseract 是一个 OCR 库, 目前由 Google 赞助(Google 也是一家以 OCR 和机器学习技术闻名于世的公司)。Tesseract 是目前公认最优秀、最精确的开源 OCR 系统,除了极高的精确度,Tesseract 也具有很高的灵活性。它可以通过训练识别出任何字体,也可以识别出任何 Unicode 字符。

2.1 Tesseract

2.1.1 引擎的安装

  • mac 环境

    brew install --with-training-tools tesseract
  • windows 环境

    下的安装可以通过 exe 安装包安装,下载地址可以从 GitHub 项目中的 wiki 找到。安装完成后记得将 Tesseract 执行文件的目录加入到 PATH 中,方便后续调用。

  • linux 环境下的安装

    sudo apt-get install tesseract-ocr

安装完后记得配置环境变量(将安装路径加到 path 里)。

注意,要想提高识别率,是需要对 Tesseract 进行训练的,两种方式:

①直接安装现成的包到”..\Tesseract-OCR\tessdata”目录下

获取链接https://github.com/tesseract-ocr/tessdata/blob/master/

②大量样本进行训练:jTessBoxEditor2.0 工具

2.1.2 Python 库的安装

  // PIL 用于打开图片文件
  pip install pillow

  // pytesseract 模块用于从图片中解析数据
  pip install pytesseract

2.2 引擎的使用

通过 pytesseract 模块的 image_to_string 方法就能将打开的图片文件中的数据提取成字符串数据,具体方法如下

from PIL import Image
import pytesseract

im = Image.open() // 指定一张图片的路径

result = pytesseract.image_to_string(im)

print(result)

二值化:

def binarizing(img, threshold):
      """ 传入 image 对象进行灰度、二值处理 """
      img = img.convert("L")  # 转灰度
      pixdata = img.load()
      w, h = img.size
      # 遍历所有像素,大于阈值的为黑色
      for y in range(h):
          for x in range(w):
              if pixdata[x, y] < threshold:
                  pixdata[x, y] = 0
              else:
                  pixdata[x, y] = 255
      return img

img = Image.open('D:\\Desktop\\asw.png')

imag=binarizing(img, 100)
imag.show()

result = pytesseract.image_to_string(imag)
print(result)

降噪:

def depoint(img):
      """ 传入二值化后的图片进行降噪 """
      pixdata = img.load()
      w, h = img.size
      for y in range(1, h - 1):
          for x in range(1, w - 1):
              count = 0
              if pixdata[x, y - 1] > 245:  # 上
                  count = count + 1
              if pixdata[x, y + 1] > 245:  # 下
                  count = count + 1
              if pixdata[x - 1, y] > 245:  # 左
                  count = count + 1
              if pixdata[x + 1, y] > 245:  # 右
                  count = count + 1
              if pixdata[x - 1, y - 1] > 245:  # 左上
                  count = count + 1
              if pixdata[x - 1, y + 1] > 245:  # 左下
                  count = count + 1
              if pixdata[x + 1, y - 1] > 245:  # 右上
                  count = count + 1
              if pixdata[x + 1, y + 1] > 245:  # 右下
                  count = count + 1
              if count > 4:
                  pixdata[x, y] = 255
      return img

2. 百度开发者平台

可以实现 OCR 的底层库并不多,目前很多库都是使用共同的几个底层 OCR 库,或者是在上面进行定制。一些人是通过机器学习的方法,自己进行训练来实现识别,但那样识别率不高,并且也较为繁琐,今天我们使用的方法是调用现成的 API, 来达成我们的目的。

API(Application Programing Interface)应用编程接口,它们为不同的应用提供了方便友好的接口。不同的开发者用不同的架构,甚至不同的语言编写软件都没问题。因为 API 设计的目的就是要成为一种通用语言,让不同的软件进行信息共享。我们通过调用百度 AI 的 API,可以使用百度 AI 的文字识别技术,响应一般以 XML 和 JSON 格式返回,经验证,百度返回的是 JSON 格式,可见 JSON 格式已经越来越流行。

一些 API 是直接可以调用的,而另一些是需要收费和认证的,百度 API 必须经过验证,它提供每天五百次免费的使用机会,对于一般人这已经足够了,下面介绍获得验证指令的方法。

注册百度账号、百度云管理中心创建应用、生成 AppKey、SecretKey(程序调用接口是要生成 access_token)

https://console.bce.baidu.com/ai/#/ai/ocr/overview/index

登陆—创建应用—获得 API Key/Secret Key

from aip import AipOcr   //pip install baidu_aip

# 你的 APPID AK SK
APP_ID = ' 你的 App ID'
API_KEY = ' 你的 Api Key'
SECRET_KEY = ' 你的 Secret Key'

client = AipOcr(APP_ID, API_KEY, SECRET_KEY)


# 读取图片
def get_file_content(filePath):
      with open(filePath, 'rb') as fp:
          return fp.read()


# 测试文件也可以写路径
image = get_file_content('images/depoint.jpg')

# 定义参数变量
options = {
      # 定义图像方向
      'detect_direction': 'true',
      # 识别语言类型,'CHN_ENG' 中英文混合
      'language_type': 'CHN_ENG',
  }

  # 调用通用文字识别接口
  results = client.basicGeneral(image, options)
  print(results)
  # 遍历取出图片解析的内容
  # for word in results['words_result']:
  #     print(word['words'])
  try:
     code = results['words_result'][0]['words']
  except:
     code = ' 验证码匹配失败 '

print(code) 

3. 打码平台

现在很多网站都会使用验证码来进行反爬,所以为了能够更好的获取数据,需要了解如何使用打码平台爬虫中的验证码

斐斐打码:http://www.fateadm.com/

4. 人工识别

通常网站只需登录一次便可爬取,在 其他识别方式不管用时,人工识别一次验证码也是可行的,其实现也非常简单——在下载完验证码图片后,调用 Image.show 方法将图片显示出来,然后调用 Python 内置的 input 函数,等待用户肉眼识别后输入识别结果。

参考

Python 利用百度文字识别 API 识别并提取图片中文字:https://blog.csdn.net/XnCSD/article/details/80786793

利用百度 API 实现文字识别:https://blog.csdn.net/JBlock/article/details/79317878


欢迎各位看官及技术大佬前来交流指导呀,可以邮件至 jqiange@yeah.net