单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,0,任务,6,反爬虫技术,主流验证码解析,任务6反爬虫技术主流验证码解析,1,本章学习目标,了解图形验证码的基本含义,掌握,tesserocr,库的安装和基本用法,了解使用,tesserocr,解析自定义图形验证码,了解滑动验证码的基本概念,了解,Selenium,和,ChromeDriver,的安装和配置并实现滑动验证码的解析,了解点击式验证码的基本概念并其技术特点,了解聚合数据平台接口的网络,API,的使用方式并实现点击式证码的解析,本章学习目标,2,6.1.5,自定义图形验证码的生成,【,实例,6-1】,本实例使用一个较为简单的图形验证码作为案例来讲解一下图形验证码解析的过程。首先,使用,Python,通过导入特定模块生成一个比较简单的图形验证码。具体步骤介绍如下:,1,)导入,random,模块,该模块用于生成图形验证码的随机数字。例如,,random.randint(a,b),,用于生成一个指定范围内的整数。其中参数,a,是下限,参数,b,是上限,生成的随机数,n:a=n=b,。,import random,2,)导入,Image,,,ImageDraw,,,ImageFont,模块,用于生成图片和字体。,Image,模块创建一个可用来对,image,进行操作的对象,对所有即将使用,ImageDraw,中操作的图片都要先进行这个对象的创建。,ImageFont,模块创建字体对象给,ImageDraw,中的,text,函数使用。这里需要首先安装,Pillow,(基于,Python,的图像库)。具体导入步骤可以参考前面章节。如图,6-14,所示。,然后在通过,PIL,导入,Image,,,ImageDraw,,,ImageFont,。,from PIL import Image,ImageDraw,ImageFont,6.1.5 自定义图形验证码的生成【实例6-1】本实例使用,3,图,6-14,安装,Pillow,图6-14 安装Pillow,4,(,3,)定义图形验证码的背景图片。使用,Image,类实例化一个长为,200px,,宽为,50px,,基于,RGB(200,220,210),颜色的图片。,image=Image.new(mode=RGB,size=(200,50),color=(200,220,210),(,4,),Draw,类实例化一支画笔,用于是实现在背景图片之上实现验证码的文字内容。,image,表示作用于的图片实例,,mode=RGB,表示采用的配色方案。,draw_brush=ImageDraw.Draw(image,mode=RGB),(,5,)定义在图形验证码中要使用的字体规格。注意:,truetype,方法中使用的字体名称一定要小写,不然会报错。,arial.ttf,表示字体风格,,28,表示字体大小。,character_font=ImageFont.truetype(arial.ttf,28),(,6,)使用,for,循环和,range(7),实现,7,次循环。循环体中使用,random.choice,方法随机选择其中生成的,ASCII,码为,65-90,的英文字母和,0-9,的数字,并分别使用,chr,和,str,方法将其转换为字符和字符串。,random.randint,方法将在每次循环过程中随机生成一种字体颜色。最后使用,draw_brush,的,text,方法实现字体的间隔为,i*30px,,纵向为,0px,,字体颜色和字体大小。,for i in range(7):,character=random.choice(chr(random.randint(65,90),str(random.randint(0,9),character_color=(random.randint(0,255),random.randint(0,255),random.randint(0,255),draw_brush.text(i*30,0,character,character_color,font=character_font),(3)定义图形验证码的背景图片。使用Image类实例化一个长,5,(,7,)使用,with open,把生成的图片保存为,test.png,格式。“,test.png”,表示当前目录中要写入的文件名称,如果没有将创建一个。“,wb”,表示将以二进制的方式写入该文件。因为保存的是一张图片,所以使用二进制的方式写入。接着使用,image,的,save,方法将该图片以“,png”,的格式保存。,with open(test.png,wb)as f:,image.save(f,format=png),(,8,)运行结果如图,6-15,所示。,图,6-15,图形验证码,(7)使用with open把生成的图片保存为t,6,完整代码如下。,import,random,from,PIL,import,Image,ImageDraw,ImageFont,image=Image.new(mode=,RGB,size=(200,40),color=(200,220,210),draw_brush=ImageDraw.Draw(image,mode=,RGB,),character_font=ImageFont.truetype(,arial.ttf,28),for,i,in,range(7):,character=random.choice(chr(random.randint(65,90),str(random.randint(0,9),character_color=(random.randint(0,255),random.randint(0,255),random.randint(0,255),draw_brush.text(i*30,0,character,character_color,font=character_font),with,open(test.png,wb)as f:,image.save(f,format=png),到此,生成一个只有数字和字母的图形验证码。该验证码的特点为:字体统一为“,arial”,,英文字母均为大写,字体之间的间隔也是固定的,30px,,每个字体的颜色是随机的。之后将是用,tesserocr,针对图形验证码进行解析操作。,完整代码如下。import randomfrom PIL,7,6.1.6 tesserocr,的基本用法,【,实例,6-2】,结合前面生成的图形验证码,这里将通过导入,tesserocr,和,PIL,的,Image,实现一个基本图形验证码解析。具体步骤介绍如下:,1,)导入,tesserocr,和,PIL,的,Image,用于图像解析。,import tesserocr,from PIL import Image,2,)使用,Image,的,open,方法打开指定,test.png,图片,该方法返回一个图像实例,并将其赋值给变量,image_to_parse,。,image_to_parse=Image.open(test.png),6.1.6 tesserocr的基本用法【实例6-2】结合,8,3,)使用,tesserocr,的,image_to_text,方法对该图像实例进行解析,该方法返回文本内容,并将其赋值给变量,text_result,。如果安装的是,Anaconda,的,Python,,这里会报错,如图,6-16,所示。错误原因是在,E:anacondainstallation,中没有找到有效的,tessdata,。因此,需要将,Tesseract-OCRtessdata,文件夹复制到,E:anacondainstallation,中(如果没有该文件夹则创建一个,这是在安装,anaconda,时让用户自定义的文件夹)即可。,text_result=tesserocr.image_to_text(image_to_parse),图,6-16 tesserocr,使用的问题,print(text_result),运行结果显示:,7U4J398,3)使用tesserocr的image_to,9,6.1.7,任务实现,使用,tesserocr,解析自定义图形验证码,【,实例,6-2】,结合前面生成的图形验证码,这里将通过导入,tesserocr,和,PIL,的,Image,实现一个基本图形验证码解析。具体步骤介绍如下:,1,)导入,tesserocr,和,PIL,的,Image,用于图像解析。,import tesserocr,from PIL import Image,2,)使用,Image,的,open,方法打开指定,test.png,图片,该方法返回一个图像实例,并将其赋值给变量,image_to_parse,。,image_to_parse=Image.open(test.png),6.1.7 任务实现使用tesserocr解析自定义图形,10,在了解了,tesserocr,的基本用法之后,现在,再找一个相对复杂的图形验证码。该图形验证码具有点状和线状的干燥图像。然后再使用上述代码运行一次,如图,6-17,所示。,图,6-17,带噪点的图形验证码,运行结果显示:,FEZJDQ,这时会发现运行的结果并不是上面生成的验证码。这是怎么回事呢?这就是前面提到的二值化,图像降噪,字符分割和特征匹配等内容了。通过观察该图形验证码,发现出现偏差应该是由于加上了干扰噪音图像的原因,所以得到了错误的结果。,在了解了tesserocr的基本用法之后,现在,再找一个,11,【,实例,6-3】,这里将借助灰度图、二值化和图像降噪等方式,通过设定阈值优化处理结果。,1,)使用,Image,对象的,convert,方法,并传入参数,L,,目的是将该图片进行灰度化,然后使用,show,方法将其显示。,image_to_convert=image_to_parse.convert(L),image_to_convert.show(),运行结果如图,6-18,所示。,图,6-18,图形验证码灰度化,【实例6-3】这里将借助灰度图、二值化和图像降噪等方式,通过,12,2,)在灰度图上,部分色彩是介于白色跟黑色之间,所以通过设置阈值的方法,把这些中间色彩全部转换成黑色跟白色。因此,通过,convert,方法传入参数,1,将灰度图像进行二值化,此时的阈值默认为,127,。二值化是指将图像上的像素点的灰度值设置为,0,或,255,,也就是将整个图片呈现出明显的只有黑和百的视觉效果。,image_to_convert=image_to_parse.convert(1),image_to_convert.show(),运行结果如图,6-19,所示。,图,6-19,图形验证码二值化,2)在灰度图上,部分色彩是介于白色跟黑色之间,所以通过,13,3,)经过不断地调试,最终设定一个比较合适的阈值,threshold,为,50,,并通过循环,将小于和大于该阈值的数据分别用,0,和,1,存入列表,chart,中,通过列表数据将图像转换成二进制,,1,表示白色,,0,就是黑色。然后,使用,point,方法根据,chart,的数据把图像做二值化处理。,threshold=50,chart=,for i in range(256):,if i threshold:,chart.append(0),else:,chart.append(1),image_for_threshold=image_to_convert.point(chart,1),image_for_threshold.show(),运行结果如图,6-20,所示。,图,6-20,图形验证码处理结果,3)经过不断地调试,最终设定一个比较合适的阈,14,4,)使用,tesserocr,的,image_to_text