栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

如果你喜欢python爬虫,

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如果你喜欢python爬虫,

今天要给大家介绍的是验证码的爬取和识别,不过只涉及到最简单的图形验证码,也是现在比较常见的一种类型。

学习Python中有不明白推荐加入交流群

                号:943752371

                群里有志同道合的小伙伴,互帮互助,

                群里有不错的学习教程!

运行平台:Windows

Python版本:Python3.6

IDE: Sublime Text

其他:Chrome浏览器

简述流程:

步骤1:简单介绍验证码

步骤2:爬取少量验证码图片

步骤3:介绍百度文字识别OCR

步骤4:识别爬取的验证码

步骤5:简单图像处理

目前,很多网站会采取各种各样的措施来反爬虫,验证码就是其中一种,比如当检测到访问频率过高时会弹出验证码让你输入,确认访问网站的不是机器人。但随着爬虫技术的发展,验证码的花样也越来越多,从最开始简单的几个数字或字母构成的图形验证码(也就是我们今天要涉及的)发展到需要点击倒立文字字母的、与文字相符合的图片的点触型验证码,需要滑动到合适位置的极验滑动验证码,以及计算题验证码等等,总之花样百出,让人头秃。验证码其他的相关知识大家可以看下这个网站:captcha.org

再来简单说下图形验证码吧,就像这张:

由字母和数字组成,再加上一些噪点,但为了防止被识别,简单的图形验证码现在也变得复杂,有的加了干扰线,有的加噪点,有的加上背景,字体扭曲、粘连、镂空、混用等等,甚至有时候人眼都难以识别,只能默默点击“看不清,再来一张”。

验证码难度的提高随之带来的就是识别的成本也需要提高,在接下来的识别过程中,我会先直接使用百度文字识别OCR,来测试识别准确度,再确认是否选择转灰度、二值化以及去干扰等图像操作优化识别率。

接下来我们就来爬取少量验证码图片存入文件。

首先打开Chrome浏览器,访问刚刚介绍的网站,里面有一个captcha图像样本链接:https://captcha.com/captcha-examples.html?cst=corg,网页里有60张不同类型的图形验证码,足够我们用来识别试验了。

直接来看代码吧:

import requests

import os

import time

from lxml import etree

def get_Page(url,headers):

response = requests.get(url,headers=headers)

if response.status_code == 200:

# print(response.text)

return response.text

return None

def parse_Page(html,headers):

html_lxml = etree.HTML(html)

datas = html_lxml.xpath('.//div[@class="captcha_images_left"]|.//div[@class="captcha_images_right"]')

item= {}

# 创建保存验证码文件夹

file = 'D:/******'

if os.path.exists(file):

os.chdir(file)

else:

os.mkdir(file)

os.chdir(file)

for data in datas:

# 验证码名称

name = data.xpath('.//h3')

# print(len(name))

# 验证码链接

src = data.xpath('.//div/img/@src')

# print(len(src))

count = 0

for i in range(len(name)):

# 验证码图片文件名

filename = name[i].text + '.jpg'

img_url = 'https://captcha.com/' + src[i]

response = requests.get(img_url,headers=headers)

if response.status_code == 200:

image = response.content

with open(filename,'wb') as f:

f.write(image)

count += 1

print('保存第{}张验证码成功'.format(count))

time.sleep(1)

def main():

url = 'https://captcha.com/captcha-examples.html?cst=corg'

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'}

html = get_Page(url,headers)

parse_Page(html,headers)

if __name__ == '__main__':

main()

仍然使用Xpath爬取,在右键检查图片时可以发现,网页分为两栏,如下图红框所示,根据class分为左右两栏,验证码分别位于两栏中。

datas = html_lxml.xpath('.//div[@class="captcha_images_left"]|.//div[@class="captcha_images_right"]')

这里我使用了Xpath中的路径选择,在路径表达式中使用“|”表示选取若干路径,例如这里表示的就是选取class为"captcha_images_left"或者"captcha_images_right"的区块。再来看下运行结果:

由于每爬取一张验证码图片都强制等待了1秒,最后这个运行时间确实让人绝望,看样子还是需要多线程来加快速度的,关于多进程多线程我们下次再说,这里我们先来看下爬取到的验证码图片。

图片到手了,接下来就是调用百度文字识别的OCR来识别这些图片了,在识别之前,先简单介绍一下百度OCR的使用方法,因为很多识别验证码的教程用的都是tesserocr库,所以一开始我也尝试过,安装过程中就遇到了很多坑,后来还是没有继续使用,而是选择了百度OCR来识别。百度OCR接口提供了自然场景下图片文字检测、定位、识别等功能。文字识别的结果可以用于翻译、搜索、验证码等代替用户输入的场景。另外还有其他视觉、语音技术方面的识别功能,大家可以直接阅读文档了解:百度OCR-API文档https://ai.baidu.com/docs#/OCR-API/top

使用百度OCR的话,首先注册用户,然后下载安装接口模块,直接终端输入pip

install baidu-aip即可。然后创建文字识别应用,获取相关Appid,API Key以及Secret

Key,需要了解一下的是百度AI每日提供50000次免费调用通用文字识别接口的使用次数,足够我们挥霍了。

然后就可以直接调用代码了。

from aip import AipOcr

# 你的 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('test.jpg')

# 调用通用文字识别, 图片参数为本地图片

result = client.basicGeneral(image)

# 定义参数变量

options = {

# 定义图像方向

'detect_direction' : 'true',

# 识别语言类型,默认为'CHN_ENG'中英文混合

'language_type' : 'CHN_ENG',

}

# 调用通用文字识别接口

result = client.basicGeneral(image,options)

print(result)

for word in result['words_result']:

print(word['words'])

这里我们识别的是这张图

可以看一下识别结果

上面是识别后直接输出的结果,下面是单独提取出来的文字部分。可以看到,除了破折号没有输出外,文字部分都全部正确输出了。这里我们使用的图片是jpg格式,文字识别传入的图像支持jpg/png/bmp格式,但在技术文档中有提到,使用jpg格式的图片上传会提高一定准确率,这也是我们爬取验证码时使用jpg格式保存的原因。

输出结果中,各字段分别代表:

log_id : 唯一的log id,用于定位问题

direction : 图像方向,传入参数时定义为true表示检测,0表示正向,1表示逆时针90度,2表示逆时针180度,3表示逆时针270度,-1表示未定义。

words_result_num : 识别的结果数,即word_result的元素个数

word_result : 定义和识别元素数组

words : 识别出的字符串

还有一些非必选字段大家可以去文档里熟悉一下。

接下来,我们要做的,就是将我们之前爬取到的验证码用刚介绍的OCR来识别,看看究竟能不能得到正确结果。

from aip import AipOcr

import os

i = 0

j = 0

APP_ID = '你的 APP_ID '

API_KEY = '你的API_KEY'

SECRET_KEY = '你的SECRET_KEY'

client = AipOcr(APP_ID, API_KEY, SECRET_KEY)

# 读取图片

file_path = 'D:******验证码图片'

filenames = os.listdir(file_path)

# print(filenames)

for filename in filenames:

# 将路径与文件名结合起来就是每个文件的完整路径

info = os.path.join(file_path,filename)

with open(info, 'rb') as fp:

# 获取文件夹的路径

image = fp.read()

# 调用通用文字识别, 图片参数为本地图片

result = client.basicGeneral(image)

# 定义参数变量

options = {

'detect_direction' : 'true',

'language_type' : 'CHN_ENG',

}

# 调用通用文字识别接口

result = client.basicGeneral(image,options)

# print(result)

if result['words_result_num'] == 0:

print(filename + ':' + '----')

i += 1

else:

for word in result['words_result']:

print(filename + ' : ' +word['words'])

j += 1

print('共识别验证码{}张'.format(i+j))

print('未识别出文本{}张'.format(i))

print('已识别出文本{}张'.format(j))

和识别图片一样,这里我们将文件夹验证码图片里的图片全部读取出来,依次让OCR识别,并依据“word_result_num”字段判断是否成功识别出文本,识别出文本则打印结果,未识别出来的用“----”代替,并结合文件名对应识别结果

。最后统计识别结果数量,再来看下识别结果。



作者:编程新视野
链接:https://www.jianshu.com/p/4f28c960ef61


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/223058.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号