千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  技术干货  > 爬虫之图片验证码处理

爬虫之图片验证码处理

来源:千锋教育
发布人:qyf
时间: 2022-09-19 17:39:37 1663580377

  了解常见验证码

  在日常生活与工作中,在进行各类设计个人账户安全的操作时,往往需要填写各种验证码来进行验证,短信、语音、文字、问答、图片、拖拽、旋转腾挪、拼图接图.......千奇百怪,各种各样,种类繁多,花样迭起!就拿奇葩验证码鼻祖的12306来说,如今我们在12306中可以碰到各种有趣,各种类型的验证码的原因,要归功于为抢票事业做出巨大贡献的——黄牛们,它的“进化史”就是一部不断与黄牛和抢票软件“斗智斗勇”的历史。

Picture

  目前我们常见的验证码,无非就是文本、图像以及音频这三大类。

Picture(1)

  而当文本验证码仍容易被机器“击破”时,图像验证码就应运而生了。通常是会提供一些物体、动物、植物、人、风景之类的图像,让我们选择正确的图像进行标记。这就是以12306为首的图像验证码了,但是这个还不算后来图像验证码又增加了新的玩法,比如旋转图片,比如拼图以及宫格,目的还是为了对抗爬虫这些机器。

Picture(2)

  接下来是音频验证码,这种相比前两种数量相对要小一些,主要是会给我们一段录音,里面有随机的单词或数字,有的会加一些噪音,我们基于录音输入其中听到的单词或数字,或者把它读出来。从安全性上来说,声音验证码比文本和图像等级要提升一个层级,因为机器想要听录音并分辨,这个难度会非常大。

Picture(3)

  验证码的处理方案

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

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

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

  图像识别引擎

  OCR,即Optical Character Recognition,光学字符识别,是指通过扫描字符,然后通过其形状将其翻译成电子文本的过程,对应图形验证码来说,它们都是一些不规则的字符,这些字符是由字符稍加扭曲变换得到的内容,我们可以使用OCR技术来讲其转化为电子文本,然后将结果提取交给服务器,便可以达到自动识别验证码的过程

  tesserocr与pytesseract是Python的一个OCR识别库,但其实是对tesseract做的一层Python API封装,pytesseract是Google的Tesseract-OCR引擎包装器;所以它们的核心是tesseract,因此在安装tesserocr之前,我们需要先安装tesseract。

  图片识别引擎环境的安装

  1 引擎的安装

  • mac环境下直接执行命令

  brew install --with-training-tools tesseract

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

  • linux环境下的安装

  sudo apt-get install tesseract-ocr

  2 Python库的安装

  # PIL用于打开图片文件

  pip/pip3 install pillow

  # pytesseract模块用于从图片中解析数据

  pip/pip3 install pytesseract

  本次案例我们使用图片识别引擎识别验证码登陆古诗文网

Picture(4)

  通过分析我们发现验证码点击刷新的链接是:

Picture(5)

  所以我们请求10次本链接获取10张图片,进行图片识别

  import time

  from PIL import Image

  import pytesseract

  import requests

  headers = {

  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"

  }

  image_url = 'https://so.gushiwen.org/RandCode.ashx'

  # 下载验证码图片

  session = requests.Session() # 使用session是为了保证验证码的请求和登陆请求信息一致

  for i in range(10):

  r = session.get(image_url, headers=headers)

  with open('images/code'+str(i)+'.jpg', 'wb') as fp:

  fp.write(r.content)

  time.sleep(10)

  print('下载完成第'+str(i)+'张!')

  # 依次识别并保存到文件中

  # 进行二值处理

  def erzhihua(image, threshold):

  ''':type image:Image.Image'''

  image = image.convert('L')

  table = []

  for i in range(256):

  if i < threshold:

  table.append(0)

  else:

  table.append(1)

  return image.point(table, '1')

  # 对刚才保存的10张图片进行识别

  for i in range(10):

  im = Image.open('images/code' + str(i) + '.jpg')

  im = erzhihua(im, 127)

  im.show()

  result = pytesseract.image_to_string(im, lang='eng')

  print(result)

  但是很遗憾10次或者更多次数才能打码成功一次。

  打码平台

  此时我们就要寻求专业的打码平台,申请第三方的平台,宋宋试了一下阿里提供的各种免费的打码平台。链接:https://market.aliyun.com/products/?keywords=图片识别验证码,但是识别效果不是很佳(哈哈因为是免费的缘故吧!只有标记优品的那个还不错其他的也可以自行试一试)。

Picture(6)

  为了测试它的识别效果,我们尝试申请成交次数最多的那个,查看官方API说明如下:

Picture(7)

  因此我们使用验证码打码平台获取验证码并登录

  实现思路:

  使用requests.session获取图片并进行本地保存

  使用打码平台识别图片

  获取登录链接,登陆链接是一个post请求,并携带了你的表单中填入的用户名和密码

  登陆获取cookies, 才能去访问用户的个人页

  import json

  from PIL import Image

  import pytesseract

  import requests

  import urllib.request

  import base64

  import ssl

  ssl._create_default_https_context = ssl._create_unverified_context

  # 1. 使用requests.session获取图片并进行本地保存

  headers = {

  "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36"

  , 'Host': 'www.xqb5200.com'

  , 'Referer': 'https://www.xqb5200.com/login.php'

  }

  session = requests.Session() # 使用session是为了保证验证码的请求和登陆请求信息一致

  code_image_url = "https://www.xqb5200.com/checkcode.php"

  r = session.get(code_image_url, headers=headers)

  with open('code.jpg', 'wb') as fp:

  fp.write(r.content)

  # 2. 使用打码平台识别图片

  # 修改API说明修改接口地址

  url = 'https://imgurlocr.market.alicloudapi.com/urlimages'

  method = 'POST'

  appcode = '你的APPCODE'

  querys = ''

  bodys = {}

  f = open(r'code.jpg', 'rb')

  contents = base64.b64encode(f.read())

  f.close()

  bodys['image'] = bytes("data:image/jpg;base64,", encoding="utf8")+contents

  post_data = urllib.parse.urlencode(bodys).encode(encoding='UTF8')

  request = urllib.request.Request(url, post_data)

  # 根据API的要求,定义相对应的Content-Type

  request.add_header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')

  request.add_header('Authorization', 'APPCODE ' + appcode)

  ctx = ssl.create_default_context()

  ctx.check_hostname = False

  ctx.verify_mode = ssl.CERT_NONE

  response = urllib.request.urlopen(request, context=ctx)

  content = response.read()

  if (content):

  code = json.loads(content.decode('utf-8'))

  print(code)

  print(code['result']['words'])

  # 3. 获取登录链接,登陆链接是一个post请求,并携带了你的表单中填入的用户名和密码

  login_url = "https://www.xqb5200.com/login.php?do=submit"

  # 用户名和密码大家可以注册一个新的用户

  data = {

  "username": "你的用户名",

  "password": "你的秘密",

  "checkcode": code,

  "action": "login",

  "submit": "%26%23160%3B%B5%C7%26%23160%3B%26%23160%3B%C2%BC%26%23160%3B"

  }

  # 4. 登陆获取cookies, 才能去访问用户的个人页

  response = session.post(url=login_url, headers=headers, data=data)

  response.encoding = 'utf-8'

  cookies = response.cookies

  # 查看登陆是否成功了

  with open('logsucess.html', 'wb') as fp:

  response.encoding = response.apparent_encoding

  fp.write(response.content)

  这样我们还是可以识别这个验证码的,如图

Picture(8)

  最后保存到本地的文件,显示登陆成功

Picture(9)

  还有滑动验证码和点触验证码的使用以及selenium+验证码登陆,期待下篇文章给大家分享...

tags:
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT