python爬虫验证码的识别

python爬虫验证码的识别,第1张

所需工具,tesserocr库和selenium库,python3.7.7

selenium库直接在你的命令行下pip install selenium就行,选python3.7.7是因为能更好的兼容tesserocr库,
tesserocr库的安装就有点麻烦了,tesserorc安装,
所有的工具都安装好了之后就可以开始 *** 作了。



这是一个专门练习爬虫验证码识别的网站

进去以后是这个样子,用户名和密码默认都是admin,接下来我们可以先小试牛刀一手看看的tesserocr的效果,先将这个上图的验证码图片另存到你想存放的文件目录下,接下来开始动手写代码

# 导入模块
import tesserocr
from PIL import Image
# 读取图片
image = Image.open('D:/picture/test2.png')
# 识别图片中的字符
txt = tesserocr.image_to_text(image)
# 答应结果
print(txt)
>>— f9.2 4

我们可以看到除了f924之外还多出来一些干扰字符-和.,这是图片里多余的像素点对识别进行了干扰,一般情况下的解决办法是将图片转换成为灰度图像然后通过阈值来对点进行筛选,然后在通过re库里面的替换模块来将多余的干扰字符全替换成none,话不多说,码如下:

# 导入模块
import tesserocr
from PIL import Image
import re
import numpy as np

image = Image.open('D:/picture/test2.png')
# 将图片转换成灰度图像,就是只有白和黑2中颜色
demo = image.convert('L')
# 将图像转换成多维数组
arr = np.array(demo)
# 设置灰度阈值,我觉得设置100读出来的像素会更清晰,你也可以换成你自己想设置的阈值
threshold = 100
# 进行筛选,超过阈值的像素变成白色,不超过像素的为黑色
arr = np.where(arr > threshold, 255, 0)
# 将筛选过后的数组又转换成图像对象
final_image = Image.fromarray(arr.astype('uint8'))
# 调用tesserocr的image_to_text将图像内容识别成文本
txt = tesserocr.image_to_text(final_image)
result = re.sub(r'\W', "", txt)
print(result)

>>f924

可以看到我们已经得到我们想要的结果字符串了,如果你对正则表达式还不了解,也没关系,你可以先记住这个用法,后面再去对正则表达式进行更多了解,接下来我们就要通过selenium这个库来模拟浏览器自动输入验证码的过程

import time
import tesserocr
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库是用来获取图片的

# 将处理验证码的方法封装成一个函数方便调用
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 = tesserocr.image_to_text(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)
# 设置登录函数
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()

这样重试了几次以后我们就能成功的登录了

到这里位置我们就能处理一般的爬虫验证码识别问题了。


谢谢大家,给个赞好吗?秋梨膏!!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/567985.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-09
下一篇 2022-04-09

发表评论

登录后才能评论

评论列表(0条)

保存