Python网络爬虫实验三:验证码处理与识别

实验三:验证码处理与识别

实验目的

针对常见的验证机制:验证码进行分析和识别,可以使用传统和 OCR 技术或者基于神经网络的机器学习技术

环境

  • Selenium 库,PyQuery 库,Chrome 和对应的 ChromeDr iver
  • 深度机器学习库和图像处理库: pytorch, python-opencv
  • OCR 库: python 第三方模块 tesserocr(这里我使用的是 pytesseract)

实验要求 1

使用一个合适的技术将登录网站 1 的验证码进行识别,并由代码自动登录。注意事项:所有信息必须由代码自动填入并且自动操作,如果人工填入任何信息或使用人工交互,此项目不得分。

实验过程

需要导入的包

import time

import numpy as np
import pytesseract
from PIL import Image
import re
from selenium import webdriver
from retrying import retry
from io import BytesIO
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException

#   retrying库是用来设置浏览器重登次数的,io库是用来获取图片的

处理验证码

  • pytesseract 将图像识别为文本
  • txt = pytesseract.image_to_string(image)
    在这里插入图片描述
# 将处理验证码的方法封装成一个函数方便调用
def process_image(image):
    """
    图片处理函数提取出正确的验证码
    :param image: 验证码图片
    :return: 返回字符串
    """
    # 将图片转换为灰度图像,只有黑和白两种颜色
    demo = image.convert('L')
    # 将图像转换为多维数组
    arr = np.array(demo)
    # 设置灰度阈值
    threshold = 100
    # 进行筛选,超过阈值的像素变为白色,没有超过的变为黑色
    arr = np.where(arr > threshold, 255, 0)
    # 将筛选过的数组又转换为图像
    final_image = Image.fromarray(arr.astype('uint8'))
    # 将图像内容识别为文本
    txt = pytesseract.image_to_string(final_image)
    # 匹配
    result = re.sub(r'\W', "", txt)
    return result

设置重登次数

# 设置了10次重登次数,当函数返回结果为false的时候就进行重试'
@retry(stop_max_attempt_number=10, retry_on_result=lambda x: x is False)

登录函数

  • css-selector 元素定位方式

    • 右键直接 copy css_selector
    • 如果元素某个属性是唯一的
      • 例:<input value="1">
      • 应用:driver.find_element(By.CSS_SELECTOR, '[value="1"]')
    • 用多个属性组合的方式定位一个元素
      • 例:<input class="a b c d" value="1">
      • 应用:driver.find_element(By.CSS_SELECTOR, '.a.b.c.d[value="1"]')
    • 各种符合的意义
      • #表示 id 属性
      • .表示 class 属性
      • []表示所有属性:[id="1"], [class="a"]
      • 如果使用标签名就不需要在前面加任何符号
        • 例:a
        • 例:input[value="1"], input 标签和 value 值组合去定位
      • >表示父子元素之间的关系
        • 例:div > input表示我们要找的元素有一个父节点是 div
      • 空格表示祖先和子孙之间的关系
        • 例:div#id input.class
        • 表示页面中有一个id="id"的 div 元素,在该 div 元素的子孙节点中有个 input 标签,该 input 标签中有个class="class"的属性,我们要定位的就是这个 input 标签
        •   <html>
            <body>
            <div id="id">
            <...>
            <input class="class">
          
  • 用户名节点并输入 admin 用户名
    在这里插入图片描述

    browser.find_element(By.CSS_SELECTOR, '.username input[type="text"]').send_keys('admin')
    
  • 密码节点并输入密码
    在这里插入图片描述

    browser.find_element(By.CSS_SELECTOR, '.password input[type="password"]').send_keys('admin')
    
  • 验证码节点并输入验证码
    在这里插入图片描述

    browser.find_element(By.CSS_SELECTOR, '.captcha input[type="text"]').send_keys(txt)
    
  • 点击登录按钮
    在这里插入图片描述

    browser.find_element(By.CSS_SELECTOR, '.login').click()
    
# 设置登录函数
def login():
    # 模拟浏览器访问练习网址
    browser.get('https://captcha7.scrape.center/')
    # 找到用户名输入这个节点并输入admin用户名
    browser.find_element(By.CSS_SELECTOR, '.username input[type="text"]').send_keys('admin')
    # 同理,找到密码输入这个节点并输入admin
    browser.find_element(By.CSS_SELECTOR, '.password input[type="password"]').send_keys('admin')
    # 验证码节点
    captcha = browser.find_element(By.CSS_SELECTOR, '#captcha')
    # 获取验证码图片
    image = Image.open(BytesIO(captcha.screenshot_as_png))
    # 调用函数处理图片识别验证码
    txt = process_image(image)
    # 输入验证码
    browser.find_element(By.CSS_SELECTOR, '.captcha input[type="text"]').send_keys(txt)
    # 点击登录按钮
    browser.find_element(By.CSS_SELECTOR, '.login').click()
    # 当登录成功这个文本所在元素出现说明登录成功,页面保留10秒后退出浏览器
    try:
        WebDriverWait(browser, 10).until(ec.presence_of_element_located((By.XPATH, '//h2[contains(., "登录成功")]')))
        time.sleep(10)
        browser.close()
        return True
    except TimeoutException:
        return False

模拟浏览器并调用登录函数

'设置模拟chrome浏览器并调用登录函数'
if __name__ == '__main__':
    browser = webdriver.Chrome()
    login()

实验要求 2

实现对于带有验证登录方式(如验证码,滑动条,拼图,语序点击,空间推理,图文点击等)的常见网站

实验过程

登录 csdn,验证方式:滑动条

导入的包

# coding=utf-8

import time

from selenium import webdriver

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
class Login():
    # 打开浏览器驱动
    def __init__(self):
        self.url = 'https://passport.csdn.net/login?code=applets'
        self.browser = webdriver.Chrome()

    # 获取登录按钮对象   选择   账号密码登录
    def get_pass_button(self):

        button = self.browser.find_element(By.XPATH, '/html/body/div[2]/div/div[2]/div[2]/div[1]/div[1]/div[1]/span[4]')
        return button

    # 打开网址,输入用户名。密码
    def open(self, username, password):
        self.browser.get(self.url)
        self.get_pass_button().click()

        self.browser.find_element(By.XPATH, '//input[@autocomplete="username"]').send_keys(username)
        time.sleep(2)
        self.browser.find_element(By.XPATH, '//input[@autocomplete="current-password"]').send_keys(password)

    # 调用    open方法,输入用户名。密码,
    # 调用  get_geetest_button方法,点击按钮
    def log(self):
        # 输入用户名密码
        self.open('***', '***')

        time.sleep(2)
        # 点击登录按钮

        self.browser.find_element(By.XPATH, '//button[@class="base-button"]').click()

        time.sleep(2)

        #    获取拖拽的滑动验证码块
        #  按钮xpath
        slideblock = self.browser.find_element(By.XPATH, '//*[@id="nc_1_n1z"]')

        # 鼠标点击滑动块不松开
        ActionChains(self.browser).click_and_hold(slideblock).perform()
        # 将圆球滑至相对起点位置的      右边xx
        ActionChains(self.browser).move_by_offset(xoffset=80, yoffset=0).perform()
        ActionChains(self.browser).move_by_offset(xoffset=160, yoffset=80).perform()
        ActionChains(self.browser).move_by_offset(xoffset=260, yoffset=160).perform()

        time.sleep(1)
        # 放开滑动块
        ActionChains(self.browser).release(slideblock).perform()


        time.sleep(10)


# 关闭浏览器,释放资源
#  self.browser.close()

# 程序主入口
if __name__ == '__main__':
    login = Login()
    login.log()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值