爬虫入门经典(十七) | 图形验证码识别

2020-11-10 14:31:32 浏览数 (1)

  大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语—不温不火,本意是希望自己性情温和。作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己所犯的错误希望能够帮助到很多和自己一样处于起步阶段的萌新。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!暂时只在csdn这一个平台进行更新,博客主页:https://buwenbuhuo.blog.csdn.net/。

一、小小课堂

在爬虫过程中,有的时候需要登录,而登录的时候一般需要验证码。

如果手动输入验证码肯定来不及的或达不到预期要求,这里就需要自动登录,这就意味着需要破解验证码。

验证码的类型有很多,常见的两类:

  • 1. 图形验证码
  • 2. 滑块验证码

验证码其实有很多种类,我们以这两种为讲解思路引导。

  • 1.文字验证码 步骤: (1)使用selenium访问 (2)将验证码图片保存 (3)识别
  • 2.滑动验证 步骤: (1)计算滑动距离 (2)模拟人滑动(总体思路是先快再慢)

实现文字验证码,可以使用图像识别技术,有很多第三方做好的图像识别接口,比如百度的图像文字识别,腾讯的图形文字识别,华为的图形文字识别。

有人可能会问:能不能自己做识别技术,肯定可以,但是需要专业领域的知识,对于现如今的我们来说是不太现实的。

也有一些专业做验证码识别的网站,比如超级鹰等。这里以超级鹰为例。

至于滑块验证此篇博文并不进行讲解,下篇博文会专门讲解此部分的实战。

在此先给出超级鹰的官网:http://www.chaojiying.com/

打开之后的效果:

二、如何使用超级鹰

  • 1. 登录或者注册
  • 2. 充值或者免费试用
  • 3. 项目中使用 找到开发文档,官方案例。

现在之后打开如下:

  • 4. 测试使用 先把测试图片和代码放到项目内

由于下载过来的测试代码有一点小问题,因此,此处给出经过博主调试正确的源码

代码语言:javascript复制
# coding:utf-8

import requests
from hashlib import md5


class Chaojiying_Client(object):

    def __init__(self, username, password, soft_id):
        self.username = username
        password = password.encode('utf8')

        self.password = md5(password).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'Connection': 'Keep-Alive',
            'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
        }


    def PostPic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()


    def ReportError(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()


if __name__ == '__main__':
    chaojiying = Chaojiying_Client('用户名', '用户密码', '908970')  # 用户中心>>软件ID 生成一个替换 96001
    im = open('./a.jpg', 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    print(chaojiying.PostPic(im, 1902)["pic_str"])  # 1902 验证码类型  官方网站>>价格体系 3.4 版 print 后要加()

此处给出的908970为生成的ID

  • 5. 运行查看识别结果

三、截取超级鹰验证码

由于此处我们需要使用到截图模块。而python页提供了pillow操作图片,我们先安装pillow模块。

代码语言:javascript复制
pip install pillow

我们先来看下登录部分的样式:

通过观察,我们看到验证码一直位于同一个部位,因此我们可以想办法先截取整个图片,然后根据位置(左上右下),确定位置在此截图,最终得到我们需要识别的验证码。 代码实现:

代码语言:javascript复制
screen_name = "./screen.png"
code_name = "./code.png"

def save_screen(driver,filename):
    # 访问网页
    driver.get('http://www.chaojiying.com/user/login/')
    # 保存当前网页图片
    driver.save_screenshot("./screen.png")

def save_code(src,dest,rectangle):
    #加载屏幕图
    img = Image.open(src)
    #截取
    img_new = img.crop(rectangle)
    # 保存
    img_new.save(dest)
    
def main():
    """主程序"""
    # 驱动文件路径
    driverfile_path = r'./chromedriver/chromedriver.exe'
    # 启动浏览器
    driver = webdriver.Chrome(driverfile_path)
    # 最大化
    driver.maximize_window()
    #循环
    while True:
        #保存屏幕图片
        save_screen(driver,filename=screen_name)
        #保存验证码图片
        save_code(screen_name,code_name,(1110,291,1290,340))

我们可以看到已经成功截取图片了,在这里可能会有的同学截取不到验证码。这是因为首先你的笔记本像素不是100%,其次的的浏览器的的比例可能也不是100%。除此之外,win7和win10也是有差距的,由于博主本人的电脑是win10系统,因此只告诉大家wein10如何确定验证码的位置。

代码语言:javascript复制
        #保存验证码图片
        save_code(screen_name,code_name,(1110,291,1290,340))

大家可能会对上述的数字不能理解,下面博主就带大家看这四个数字都是干什么的。

首先我们先对保存的图片screen使用系统自带的画图打开

下面我们点击验证码的左上方

下面点击验证码的右下方

这个时候就应该明白那四个数字分别代表什么了把。

四、识别验证码

现在我们已经保存了验证码下一步就是要识别验证码。 首先,我们要导入下载的官方demo,然后对刚截取的验证码进行识别,最终给出识别的验证码

代码语言:javascript复制
from chaojiying import Chaojiying_Client

def decern_code(filename):
    """识别"""
    chaojiying = Chaojiying_Client('自己的用户名', '自己的密码', '908970')  # 用户中心>>软件ID 生成一个替换 96001
    im = open(filename, 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    content =  chaojiying.PostPic(im, 1902)  # 1902 验证码类型  官方网站>>价格体系 3.4 版 print 后要加()
    return content.get("pic_str")

?到这时候,我们就需要查看如何模拟登录页面了

五、模拟登录

5.1 分析

通过查看页面,我们可以知道模拟登录分别需要用户名、密码、验证码、点击登录四步。下面我们就来分析这四步

  • 1.用户名
  • 2. 用户密码
  • 3. 验证码输入
  • 4. 点击登录

5.2 代码实现

代码语言:javascript复制
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input").send_keys(username)
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input").send_keys(password)
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input").send_keys(code)
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input").click()

六、 完整代码

代码语言:javascript复制
# encoding: utf-8
'''
  @author 李华鑫
  @create 2020-10-10 11:41
  Mycsdn:https://buwenbuhuo.blog.csdn.net/
  @contact: 459804692@qq.com
  @software: Pycharm
  @file: 超级鹰图片验证.py
  @Version:1.0
  
'''
from time import sleep
from selenium import webdriver
from PIL import Image
from chaojiying import Chaojiying_Client
import time

screen_name = "./screen.png"
code_name = "./code.png"

def save_screen(driver,filename):
    # 访问网页
    driver.get('http://www.chaojiying.com/user/login/')
    # 保存当前网页图片
    driver.save_screenshot("./screen.png")

def save_code(src,dest,rectangle):
    #加载屏幕图
    img = Image.open(src)
    #截取
    img_new = img.crop(rectangle)
    # 保存
    img_new.save(dest)

def decern_code(filename):
    """识别"""
    chaojiying = Chaojiying_Client('ymmymm', 'ymm123456', '908970')  # 用户中心>>软件ID 生成一个替换 96001
    im = open(filename, 'rb').read()  # 本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    content =  chaojiying.PostPic(im, 1902)  # 1902 验证码类型  官方网站>>价格体系 3.4 版 print 后要加()
    return content.get("pic_str")

def login(driver,username,password,code):
    """登录"""
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input").send_keys(username)
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input").send_keys(password)
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input").send_keys(code)
    driver.find_element_by_xpath("/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input").click()
    time.sleep(2)
    if driver.title == "用户登录-超级鹰验证码识别代答题平台":
        return False
    else:
        return True

def main():
    """主程序"""
    # 驱动文件路径
    driverfile_path = r'./chromedriver/chromedriver.exe'
    # 启动浏览器
    driver = webdriver.Chrome(driverfile_path)
    # 最大化
    driver.maximize_window()
    #循环
    while True:
        #保存屏幕图片
        save_screen(driver,filename=screen_name)
        #保存验证码图片
        save_code(screen_name,code_name,(1110,291,1290,340))
        #识别验证码图片
        code = decern_code(code_name)
        #登录
        ret = login(driver,"ymmymm","ymm123456",code)
        if ret:#登录成功
            print("登录成功")
            break
        else:#登录失败
            print("失败...重新再来...")
    # 退出
    driver.quit()

if __name__ == '__main__':
    main()

七、运行过程及结果

美好的日子总是短暂的,虽然还想继续与大家畅谈,但是本篇博文到此已经结束了,如果还嫌不够过瘾,不用担心,我们下篇见!


  好书不厌读百回,熟读课思子自知。而我想要成为全场最靓的仔,就必须坚持通过学习来获取更多知识,用知识改变命运,用博客见证成长,用行动证明我在努力。   如果我的博客对你有帮助、如果你喜欢我的博客内容,请“点赞” “评论”“收藏”一键三连哦!听说点赞的人运气不会太差,每一天都会元气满满呦!如果实在要白嫖的话,那祝你开心每一天,欢迎常来我博客看看。   码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘了关注我哦!

0 人点赞