朋友们大家好,python爬虫是在学习python时比较容易上手的学习方式,爬虫的思路简要以下几点:

1.获取需要爬取页面的网址,并且对网页内容进行分析。(主要就源代码讨论,如果我们需要的内容没有在源代码出现,则需要进行抓包分析)

2.找到我们需要爬取的内容时我们就要用正则表达式、beautifulsoup或者是xpath进行切割我们需要的字段。

3.将爬取到的内容进行存储。

这是一般网站爬取的基本点,但是我们在遇到需要登陆或者注册的网站时就会遇到验证码,验证码的出现就是为了区分人和机器,但是随着现在人工智能的发展,这种区分已经不明确了,在python中有PIL库进行图像处理、机器学习也能更好地解决验证码的问题,下面就中国执行信息公开网(http://shixin.court.gov.cn/)给大家进行详细的讲解。

咳咳   大家注意这一行字!!!!!!!!

一、事前准备

1.python版本    python2.7

2.系统版本   ubantu 16.04

3.所需库

import urllib2
    import urllib
    from bs4 import BeautifulSoup 
    import time
    import re

import requests(包含了我爬取"中国执行信息公开网"的所有用到的库)

使用了beautifulsoup+正则表达式的方式提取我需要的内容

二、查看网站

推荐使用谷歌浏览器     使用F12键进入前端调试(有的电脑需要使用Fn+F12  比如我的)

火狐浏览器显示我实在不喜欢,所以推荐使用谷歌的  有喜欢火狐的童鞋们也可以使用

点击进来我们可以看到一个类似于登陆和注册的查询表单,我们通过查看页面源代码可以发现下图这样的信息

可以发现我们需要的是pname、pcardname、pprovince以及我们需要的验证码pcode。然后我就想直接写入这些内容直接post响应,然后我发现以下:

出现错误,点开F12可以发现post响应中提交了五个信息:

那么最后一个信息我们应该能够猜到是和验证码绑定的id号(比如说我们两个人同时登陆网站,同时提交了验证码然后进行验证,系统如何知道我们提交的验证码是否正确,就是通过绑定的id号来识别)所以我们现在的工作就是要找到对应的id号。

三、找到对应的id号

首先通过分析get响应可以发现我们实际提交的表单在网页    http://shixin.court.gov.cn/index_new_form.do中,打开链接能够看到:

这就是一个单独版的表单嘛!!查看源代码:

能够看到:

src="captchaNew.do?captchaId=39821d3fd1a2470ca658bb18585093fc&random=0.4255476101932901" title="点击重新获取验证码"

onclick="this.src='captchaNew.do?captchaId=39821d3fd1a2470ca658bb18585093fc&random=0.4984367166835566'"

能够发现id号隐藏在其中的,还有random号,共同组成了我们需要查看的网页(感觉就是把原网页进行了分割)

这一部分代码的实现我是采用了beautifulsoup实现的,代码如下:

url="http://shixin.court.gov.cn/index_new_form.do"
data=requests.get(url).content.encode('utf-8')
soup=BeautifulSoup(data,'lxml')
captchaId = soup.find('img',attrs={'id':'captchaImg'})['src'].split('?')[1].split('&')[0].split('=')[1]

四、识别验证码

扯了这么多现在回到我们最原始的问题,那么我们应该怎么去识别验证码呢?

首先我们要了解python的图像识别库 python image libary,叫做PIL库

1.首先要安装pil库,pip install pil不能安装的童鞋可以参考这篇文章

2. pytesser(识别验证码的库,需要使用Tesseract这个开源项目)

3.Tesseract

全部安装完成后我们就要对网站的验证码进行查看

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sys
import urllib2
import urllib
import time
import re
reload(sys)
sys.setdefaultencoding('utf8')  headers=("User-Agent",
"Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/60.0")
opener=urllib2.build_opener()
opener.addheaders=[headers]
urllib2.install_opener(opener)for i in range(1,1500):url="http://shixin.court.gov.cn/captchaNew.do?captchaId=6eb54a8c64f84a84b6490db24671c310&random="+str(i)data=urllib2.urlopen(url).read()#data=urllib2.quote(data).decode('utf-8')file="/home/yang/png/test/"+str(i)+".png"playFile = open(file, 'wb')playFile.write(data)playFile.close()time.sleep(1)

通过这部分代码可以在执行信息公开网上下载验证码,我们可以发现,其实验证码就这几种:

         

1.第一种看似很简单,但能够看到它整体有一种毛糙感,(浑身都是噪点的感觉,具体也不是专业做这方面的,对这块也不熟悉,反正这个验证码还不能解决,希望和大大们一起探讨探讨)

2.这种验证码含有干扰线,但我们能够发现颜色占主体的还是四个字符,所以我们可以通过获取颜色最多的四种颜色来去除干扰线

3.第三种就十分简单了,整体扭曲的程度也不大,可以直接使用pytesseract.image_to_string()来得到

五、对验证码的处理

对验证码的处理大致分为:去除噪点、去除干扰线(如果存在干扰线)、二值化(生成灰度图)

1.去除噪点,直接上代码:

def fall (img):#img:图片地址 white = (255,255,255,255)black = (0,0,0,255)#img = Image.open('/home/yang/png/0.png') # 读入图片pixdata = img.load()X = img.size[0]-1#因为我校的验证码二值化后正好剩下一圈宽度为一像素的白边,所以这么处理了Y = img.size[1]-1def icolor(RGBA):if RGBA == white:return(1)else:return(0)for y in range(Y):for x in range(X):if (x<1 or y<1):passelse:if icolor(pixdata[x,y]) == 1:passelse:if (icolor(pixdata[x+1,y])+icolor(pixdata[x,y+1])+icolor(pixdata[x-1,y])+icolor(pixdata[x,y-1])+icolor(pixdata[x-1,y-1])+icolor(pixdata[x+1,y-1])+icolor(pixdata[x-1,y+1])+icolor(pixdata[x+1,y+1]))>6: #如果一个黑色像素周围的8个像素中白色像素数量大于5个,则判断其为噪点,填充为白色pixdata[x,y] = white #填充白点       for y in range(Y):for x in range(X):if (x<1 or y<1):passelse:if icolor(pixdata[x,y]) == 0:passelse:if ((icolor(pixdata[x+1,y]))+(icolor(pixdata[x,y+1]))+(icolor(pixdata[x-1,y]))+(icolor(pixdata[x,y-1])))<2:#如果一个白色像素上下左右4个像素中黑色像素的个数大于2个,则判定其为有效像素,填充为黑色。pixdata[x,y] = black#二次去除黑点   for y in range(Y):for x in range(X):if (x<1 or y<1):passelse:if icolor(pixdata[x,y]) == 1:passelse:if (icolor(pixdata[x+1,y])+icolor(pixdata[x,y+1])+icolor(pixdata[x-1,y])+icolor(pixdata[x,y-1]))>2:pixdata[x,y] = whiteimg.save('保存地址')

2.去除干扰线

def ganraoxian(img):#img:图片地址#img = Image.open('/home/yang/png/'+str(i)+'.png') # 读入图片width = img.size[0]heigth = img.size[1]  #获取长宽smap={}slist=[]keylist=[]for i in range(0,width):for j in range(0,heigth):argb = img.getpixel((i,j))r = argb[0]g = argb[1]b = argb[2]sum = r + g + b   #得到每一点的rgbif sum not in smap.keys():  #如果没有该sum值的点  进行添加  并且给值为1smap[sum]=1else:num=smap[sum]       smap[sum]=num+1  #如果有了这个值  在原基础上+1slist=sorted(smap.items(),key=lambda x:x[1],reverse = False)if (len(slist) > 4):num1 = slist[len(slist) - 5][1]num2 = slist[len(slist) - 4][1]num3 = slist[len(slist) - 3][1]num4 = slist[len(slist) - 2][1]     #获取像素点最多的四个点for key in smap:if smap[key] == num1 or smap[key] == num2 or smap[key] == num3 or smap[key] == num4 :#if num1 in smap or num2 in smap or num3 in smap or num4 in smap :keylist.append(key)      #找到对应颜色的点for x in range(0,width):for y in range(0,heigth):argb = img.getpixel((x,y))r = argb[0]g = argb[1]b = argb[2]ssum = r + g + b flag = Truefor i in range(1,3): #px+1if y + i < heigth and y - i > 0 and x - i > 0 and x + i < width:upargb = img.getpixel((x,y-i))endargb = img.getpixel((x,y+i))rightupargb = img.getpixel((x+i,y+i))leftupargb = img.getpixel((x-i,y+i))leftdownargb = img.getpixel((x-i,y-i))rightdownargb = img.getpixel((x+i,y-i))r1 = upargb[0]g1 = upargb[1]b1 = upargb[2]sum1 = r1 + g1 + b1r2 = endargb[0]g2 = endargb[1]b2 = endargb[2]sum2 = r2 + g2 + b2r3 = rightupargb[0]g3 = rightupargb[1]b3 = rightupargb[2]sum3 = r3 + g3 + b3r4 = leftupargb[0]g4 = leftupargb[1]b4 = leftupargb[2]sum4 = r4 + g4 + b4r5 = leftdownargb[0]g5 = leftdownargb[1]b5 = leftdownargb[2]sum5 = r5 + g5 + b5r6 = rightdownargb[0]g6 = rightdownargb[1]b6 = rightdownargb[2]sum6 = r6 + g6 + b6if sum1 in keylist or sum2 in keylist or sum3 in keylist or sum4 in keylist or sum5 in keylist or sum6 in keylist:flag = Falseif (ssum not in keylist and flag):img.putpixel((x,y),(255,255,255))for x in range(0,width):for y in range(0,heigth):    if img.getpixel((x,y))==(255,255,255,255):continueelse:img.putpixel((x,y),(0,0,0,255))#curImg.setRGB(x, y, Color.white.getRGB())  img.save('保存地址‘) 

得到了的结果是

          

我们会发现虽然去掉了干扰线,但是对应的有很多地方会缺失内容,会导致不能直接使用pytesseract.image_to_string()直接进行读取,就必须采用机器学习的方式来读取(期待有更好更简单的方法

注意:这里因为是通过不同的颜色进行区分,所以我们必须在二值化之前进行去除干扰线的操作。另外一种添加干扰线的方式是添加多条较细的线条,这里可以根据线条的宽度进行区别实现去除操作。

3.二值化处理

def two(img): #img:图片地址 i = 0#img = Image.open('/home/yang/png/0.png') # 读入图片img = img.convert("RGBA")while i < 4:#循环次数视情况进行调整i = i+1pixdata = img.load()#一次二值化for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][0] < 90:#使RGB值中R小于90的像素点变成纯黑pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][1] < 190:#使RGB值中G小于90的像素点变成纯黑pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][2] > 0:#使RGB值中B大于0的像素点变成纯白pixdata[x, y] = (255, 255, 255, 255)#理论上的二值化代码只有上面那些,RGB值的调整阈值需要针对不同验证码反复调整。同时实际中一组阈值往往没法做到完美,后面的部分是视实际情况添加的类似部分#二次二值化(除去某些R、G、B值接近255的颜色)                 for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][0] < 254:pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][1] < 254:pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][2] > 0:pixdata[x, y] = (255, 255, 255, 255)#三次二值化,怼掉纯黄色(实际使用中发现很多图片最后剩几个纯黄色的像素点)               for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y] ==(255,255,0,255):pixdata[x, y] = (0, 0, 0, 255)img.save('保存地址')

使图像变为黑白方便读取

在这里可以看出来,如果要去掉干扰线,必须要在二值化之前进行。

六、读取验证码上的信息

首先提供一种简便的方法:

info = Image.open("图片的路径")
image_info = pytesseract.image_to_string(info)
print image_info

没错,就这么三行代码,就能读取验证码上的信息,但是这种方法只能够识别没有扭曲、没有变形和没有干扰线不粘连的验证码。

能够看出来读取的效率的确很低,经过变形的验证码几乎不能实现,对于扭曲变形的验证码,我查阅了很多资料,但是还是没有什么解决办法,希望能够和相关大牛进行交流交流。

七、利用机器学习进行识别验证码(这一部分内容我是根据这篇文章学习的来的,对我帮助很大)

首先我们要解决大小写字母和数字一个62个矩阵和本身的转换

#coding: utf-8
import os
import random
from PIL import Image
import numpy as np
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import random
import sys
reload(sys)
sys.setdefaultencoding('utf8')IMAGE_HEIGHT = 70
IMAGE_WIDTH = 160
MAX_CAPTCHA = 4
CHAR_SET_LEN = 62def get_name_and_image():all_image = os.listdir('/home/yg/study/yanzhengjixiexuexi/captch/images')random_file = random.randint(0, 489)print random_filebase = os.path.basename('/home/yg/study/yanzhengjixiexuexi/captch/images/' + all_image[random_file])name = os.path.splitext(base)[0] #将文件名和后缀分开print name,baseimage = Image.open('/home/yg/study/yanzhengjixiexuexi/captch/images/' + all_image[random_file])image = np.array(image)print image[35]return name, image#print get_name_and_image()def name2vec(name):vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)print len(vector)for i, c in enumerate(name):print i,c,ord(c)    #大小写字母和数字分别进行矩阵的转换if ord(c)>58 and ord(c)<=90:idx = i * 62 + ord(c) - 65vector[idx] = 1elif ord(c)>=97 and ord(c)<=122:idx = i * 62 + ord(c) - 71vector[idx] = 1else:idx = i * 62 + ord(c) + 4vector[idx] = 1return vector
print name2vec('AZaz')[0]
print name2vec('az09')[0]def vec2name(vec):x=0name=[]for one_vec in vec:if one_vec==1:if x<=25:name.append(chr(x+65))elif x<=51:name.append(chr(x-26+97))else:name.append(chr(x-52+49))    x+=1if x>=62:x=0return "".join(name)print vec2name(name2vec('AZaz'))

得到的结果为

基本就根据https://www.jianshu.com/p/26ff7b9075a1?from=timeline该网页方法完成,总代码如下:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from PIL import Image
import numpy as np
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
import random
import sys
reload(sys)
sys.setdefaultencoding('utf8')IMAGE_HEIGHT = 114
IMAGE_WIDTH = 450
MAX_CAPTCHA = 6
CHAR_SET_LEN = 26'''
IMAGE_HEIGHT = 70
IMAGE_WIDTH = 160
MAX_CAPTCHA = 4
CHAR_SET_LEN = 36def get_name_and_image():all_image = os.listdir('/home/yang/captch/images/')random_file = random.randint(0, 3429)base = os.path.basename('/home/yang/captch/images/' + all_image[random_file])name = os.path.splitext(base)[0]image = Image.open('/home/yang/captch/images/' + all_image[random_file])image = np.array(image)return name, image
'''def get_name_and_image():all_image = os.listdir('/home/yang/桌面/captcha4/')random_file = random.randint(0, 3429)base = os.path.basename('/home/yang/桌面/captcha4/' + all_image[random_file])name = os.path.splitext(base)[0] #将文件名和后缀分开image = Image.open('/home/yang/桌面/captcha4/' + all_image[random_file])image = np.array(image)return name, imagedef name2vec(name):
    vector = np.zeros(MAX_CAPTCHA*CHAR_SET_LEN)
    print len(vector)
    for i, c in enumerate(name):
        print i,c,ord(c)
        if ord(c)>58 and ord(c)<=90:
            idx = i * 62 + ord(c) - 65
            vector[idx] = 1
        elif ord(c)>=97 and ord(c)<=122:
            idx = i * 62 + ord(c) - 71
            vector[idx] = 1
        else:
            idx = i * 62 + ord(c) + 4
            vector[idx] = 1
    return vector
print name2vec('AZaz')[0]
print name2vec('az09')[0]def vec2name(vec):
    x=0
    name=[]
    for one_vec in vec:
        if one_vec==1:
            if x<=25:
                name.append(chr(x+65))
            elif x<=51:
                name.append(chr(x-26+97))
            else:
                name.append(chr(x-52+49))
        x+=1
        if x>=62:
            x=0

    return "".join(name)# 生成一个训练batch
def get_next_batch(batch_size=64):batch_x = np.zeros([batch_size, IMAGE_HEIGHT*IMAGE_WIDTH])batch_y = np.zeros([batch_size, MAX_CAPTCHA*CHAR_SET_LEN])for i in range(batch_size):name, image = get_name_and_image()batch_x[i, :] = 1*(image.flatten())batch_y[i, :] = name2vec(name)return batch_x, batch_y####################################################X = tf.placeholder(tf.float32, [None, IMAGE_HEIGHT*IMAGE_WIDTH])
Y = tf.placeholder(tf.float32, [None, MAX_CAPTCHA*CHAR_SET_LEN])
keep_prob = tf.placeholder(tf.float32)# 定义CNN
def crack_captcha_cnn(w_alpha=0.01, b_alpha=0.1):x = tf.reshape(X, shape=[-1, IMAGE_HEIGHT, IMAGE_WIDTH, 1])# 3 conv layerw_c1 = tf.Variable(w_alpha * tf.random_normal([5, 5, 1, 32]))b_c1 = tf.Variable(b_alpha * tf.random_normal([32]))conv1 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(x, w_c1, strides=[1, 1, 1, 1], padding='SAME'), b_c1))conv1 = tf.nn.max_pool(conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')conv1 = tf.nn.dropout(conv1, keep_prob)w_c2 = tf.Variable(w_alpha * tf.random_normal([5, 5, 32, 64]))b_c2 = tf.Variable(b_alpha * tf.random_normal([64]))conv2 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv1, w_c2, strides=[1, 1, 1, 1], padding='SAME'), b_c2))conv2 = tf.nn.max_pool(conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')conv2 = tf.nn.dropout(conv2, keep_prob)w_c3 = tf.Variable(w_alpha * tf.random_normal([5, 5, 64, 64]))b_c3 = tf.Variable(b_alpha * tf.random_normal([64]))conv3 = tf.nn.relu(tf.nn.bias_add(tf.nn.conv2d(conv2, w_c3, strides=[1, 1, 1, 1], padding='SAME'), b_c3))conv3 = tf.nn.max_pool(conv3, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')conv3 = tf.nn.dropout(conv3, keep_prob)# Fully connected layerw_d = tf.Variable(w_alpha * tf.random_normal([15 * 57 * 64, 1024]))b_d = tf.Variable(b_alpha * tf.random_normal([1024]))dense = tf.reshape(conv3, [-1, w_d.get_shape().as_list()[0]])dense = tf.nn.relu(tf.add(tf.matmul(dense, w_d), b_d))dense = tf.nn.dropout(dense, keep_prob)w_out = tf.Variable(w_alpha * tf.random_normal([1024, MAX_CAPTCHA * CHAR_SET_LEN]))b_out = tf.Variable(b_alpha * tf.random_normal([MAX_CAPTCHA * CHAR_SET_LEN]))out = tf.add(tf.matmul(dense, w_out), b_out)return out# 训练
def train_crack_captcha_cnn():output = crack_captcha_cnn()loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=output, labels=Y))optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss)predict = tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN])max_idx_p = tf.argmax(predict, 2)max_idx_l = tf.argmax(tf.reshape(Y, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)correct_pred = tf.equal(max_idx_p, max_idx_l)accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))saver = tf.train.Saver()with tf.Session() as sess:sess.run(tf.global_variables_initializer())step = 0while True:batch_x, batch_y = get_next_batch(64)_, loss_ = sess.run([optimizer, loss], feed_dict={X: batch_x, Y: batch_y, keep_prob: 0.5})print(step, loss_)# 每100 step计算一次准确率if step % 100 == 0:batch_x_test, batch_y_test = get_next_batch(100)acc = sess.run(accuracy, feed_dict={X: batch_x_test, Y: batch_y_test, keep_prob: 1.})print("steps=%d, accuracy=%f" % (step, acc))# 如果准确率大于50%,保存模型,完成训练if acc > 0.99:saver.save(sess, "./crack_capcha.model", global_step=step)breakstep += 1train_crack_captcha_cnn()#训练完成后#掉train_crack_captcha_cnn(),取消下面的注释,开始预测,注意更改预测集目录# def crack_captcha():
#     output = crack_captcha_cnn()
#
#     saver = tf.train.Saver()
#     with tf.Session() as sess:
#         saver.restore(sess, tf.train.latest_checkpoint('.'))
#         n = 1
#         while n <= 10:
#             text, image = get_name_and_image()
#             image = 1 * (image.flatten())
#             predict = tf.argmax(tf.reshape(output, [-1, MAX_CAPTCHA, CHAR_SET_LEN]), 2)
#             text_list = sess.run(predict, feed_dict={X: [image], keep_prob: 1})
#             vec = text_list[0].tolist()
#             predict_text = vec2name(vec)
#             print("正确: {}  预测: {}".format(text, predict_text))
#             n += 1
#
# crack_captcha()

附上获取验证码的全部代码

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import pytesseract
from PIL import Image
import sys
import re
reload(sys)
sys.setdefaultencoding('utf8')###############################################
###############################################
##########去除干扰线
def ganraoxian(img,k):width = img.size[0]heigth = img.size[1]  #获取长宽smap={}slist=[]keylist=[]for i in range(0,width):for j in range(0,heigth):argb = img.getpixel((i,j))r = argb[0]g = argb[1]b = argb[2]sum = r + g + b   #得到每一点的rgbif sum not in smap.keys():  #如果没有该sum值的点  进行添加  并且给值为1smap[sum]=1else:num=smap[sum]       smap[sum]=num+1  #如果有了这个值  在原基础上+1slist=sorted(smap.items(),key=lambda x:x[1],reverse = False)if (len(slist) > 4):num1 = slist[len(slist) - 5][1]num2 = slist[len(slist) - 4][1]num3 = slist[len(slist) - 3][1]num4 = slist[len(slist) - 2][1]     #获取像素点最多的四个点for key in smap:if smap[key] == num1 or smap[key] == num2 or smap[key] == num3 or smap[key] == num4 :#if num1 in smap or num2 in smap or num3 in smap or num4 in smap :keylist.append(key)      #找到对应颜色的点for x in range(0,width):for y in range(0,heigth):argb = img.getpixel((x,y))r = argb[0]g = argb[1]b = argb[2]ssum = r + g + b flag = Truefor i in range(1,3): #px+1if y + i < heigth and y - i > 0 and x - i > 0 and x + i < width:upargb = img.getpixel((x,y-i))endargb = img.getpixel((x,y+i))rightupargb = img.getpixel((x+i,y+i))leftupargb = img.getpixel((x-i,y+i))leftdownargb = img.getpixel((x-i,y-i))rightdownargb = img.getpixel((x+i,y-i))r1 = upargb[0]g1 = upargb[1]b1 = upargb[2]sum1 = r1 + g1 + b1r2 = endargb[0]g2 = endargb[1]b2 = endargb[2]sum2 = r2 + g2 + b2r3 = rightupargb[0]g3 = rightupargb[1]b3 = rightupargb[2]sum3 = r3 + g3 + b3r4 = leftupargb[0]g4 = leftupargb[1]b4 = leftupargb[2]sum4 = r4 + g4 + b4r5 = leftdownargb[0]g5 = leftdownargb[1]b5 = leftdownargb[2]sum5 = r5 + g5 + b5r6 = rightdownargb[0]g6 = rightdownargb[1]b6 = rightdownargb[2]sum6 = r6 + g6 + b6if sum1 in keylist or sum2 in keylist or sum3 in keylist or sum4 in keylist or sum5 in keylist or sum6 in keylist:flag = Falseif (ssum not in keylist and flag):img.putpixel((x,y),(255,255,255))for x in range(0,width):for y in range(0,heigth):    if img.getpixel((x,y))==(255,255,255,255):continueelse:img.putpixel((x,y),(0,0,0,255))#curImg.setRGB(x, y, Color.white.getRGB())  img.save('图片地址') '''
#############################################
#############################################
########读取验证码
def readcCode():try:img = Image.open('图片地址')text = pytesseract.image_to_string (img)text = text.replace(' ', '')if text == "":#如果识别结果为空,则识别失败tip = Falseif re.search(r'[0-9a-zA-Z]{4}',text):passelse:tip = False#如果识别结果中出现了了字母数字之外的字符,则识别失败if len(text) !=4:tip = False#如果识别结果不足四位(因为有部分字符粘连的验证码),则识别失败except UnicodeDecodeError as e:tip = False #如果报字符编码错误,则识别失败,需要捕捉错误if tip == False:#识别失败return (readcCode())#如果识别失败,迭代、重新识别(实际使用中需要调用验证码获取函数重新获取验证码)else:return(text)readcCode()
'''##################################################
##################################################
###################二值化
def two(img,j):i = 0img = img.convert("RGBA")while i < 4:#循环次数视情况进行调整i = i+1pixdata = img.load()#一次二值化for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][0] < 90:#使RGB值中R小于90的像素点变成纯黑pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][1] < 190:#使RGB值中G小于90的像素点变成纯黑pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][2] > 0:#使RGB值中B大于0的像素点变成纯白pixdata[x, y] = (255, 255, 255, 255)#理论上的二值化代码只有上面那些,RGB值的调整阈值需要针对不同验证码反复调整。同时实际中一组阈值往往没法做到完美,后面的部分是视实际情况添加的类似部分#二次二值化(除去某些R、G、B值接近255的颜色)                 for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][0] < 254:pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][1] < 254:pixdata[x, y] = (0, 0, 0, 255)for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y][2] > 0:pixdata[x, y] = (255, 255, 255, 255)#三次二值化,怼掉纯黄色(实际使用中发现很多图片最后剩几个纯黄色的像素点)               for y in range(img.size[1]):for x in range(img.size[0]):if pixdata[x, y] ==(255,255,0,255):pixdata[x, y] = (0, 0, 0, 255)img.save(’图片地址‘)####################################################
####################################################
########################去噪
#一次清除黑点
def fall (img,j):white = (255,255,255,255)black = (0,0,0,255)pixdata = img.load()X = img.size[0]-1#因为我校的验证码二值化后正好剩下一圈宽度为一像素的白边,所以这么处理了Y = img.size[1]-1def icolor(RGBA):if RGBA == white:return(1)else:return(0)for y in range(Y):for x in range(X):if (x<1 or y<1):passelse:if icolor(pixdata[x,y]) == 1:passelse:if (icolor(pixdata[x+1,y])+icolor(pixdata[x,y+1])+icolor(pixdata[x-1,y])+icolor(pixdata[x,y-1])+icolor(pixdata[x-1,y-1])+icolor(pixdata[x+1,y-1])+icolor(pixdata[x-1,y+1])+icolor(pixdata[x+1,y+1]))>6: #如果一个黑色像素周围的8个像素中白色像素数量大于5个,则判断其为噪点,填充为白色pixdata[x,y] = white #填充白点       for y in range(Y):for x in range(X):if (x<1 or y<1):passelse:if icolor(pixdata[x,y]) == 0:passelse:if ((icolor(pixdata[x+1,y]))+(icolor(pixdata[x,y+1]))+(icolor(pixdata[x-1,y]))+(icolor(pixdata[x,y-1])))<2:#如果一个白色像素上下左右4个像素中黑色像素的个数大于2个,则判定其为有效像素,填充为黑色。pixdata[x,y] = black#二次去除黑点   for y in range(Y):for x in range(X):if (x<1 or y<1):passelse:if icolor(pixdata[x,y]) == 1:passelse:if (icolor(pixdata[x+1,y])+icolor(pixdata[x,y+1])+icolor(pixdata[x-1,y])+icolor(pixdata[x,y-1]))>2:pixdata[x,y] = whiteimg.save('图片地址')#########################################################
#########################################################
#####
for i in range (541,542):im = Image.open('图片地址') # 读入图片fall(im,i)ganraoxian(im,i)#time.sleep(1)two(im,i)
'''
info = Image.open("/home/yang/png/elx6.png")
image_info = pytesseract.image_to_string(info)
print image_info
'''

进行到这里基本就完成了验证码的识别,作为快进入大四的学生,越学习相关知识越发现自己还有很多东西要学习,这篇博客是我第一篇博客,存在很多不足的地方,希望大家指正。最后感谢小鱼干帮我修改

最后附上直接运行就能获取验证码的代码:

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
import sys
import urllib2
import urllib
import time
import re
reload(sys)
sys.setdefaultencoding('utf8')  headers=("User-Agent",
"Mozilla/5.0 (X11; Ubuntu; Linu…) Gecko/20100101 Firefox/60.0")
opener=urllib2.build_opener()
opener.addheaders=[headers]
urllib2.install_opener(opener)for i in range(659,1500):url="http://shixin.court.gov.cn/captchaNew.do?captchaId=6eb54a8c64f84a84b6490db24671c310&random="+str(i)data=urllib2.urlopen(url).read()#data=urllib2.quote(data).decode('utf-8')file="/home/yang/png/test/"+str(i)+".png"playFile = open(file, 'wb')playFile.write(data)playFile.close()time.sleep(1)

python爬虫遇到验证码的处理方法(以爬取中国执行信息公开网为例)相关推荐

  1. Python实战案例:爬取中国执行信息公开网

    从面试题谈起 谈到这个项目的爬虫,就要从一道面试题谈起了. 这道面试题是: 请写一个爬虫从网址 http://zxgk.court.gov.cn/shixin/,检索被执行人姓名:"阿里&q ...

  2. Python爬虫实战,requests+openpyxl模块,爬取手机商品信息数据(附源码)

    前言 今天给大家介绍的是Python爬取手机商品信息数据,在这里给需要的小伙伴们代码,并且给出一点小心得. 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫,基本的是加请求头,但是这样的纯文本 ...

  3. Python爬虫实战,requests+parsel模块,爬取二手房房源信息数据

    前言 最近在尝试用Python爬虫二手房房源信息数据,在这里给需要的小伙伴们提供代码,并且给出一点小心得. 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫,基本的是加请求头,但是这样的纯文本 ...

  4. Python爬虫与一汽项目【三】爬取中国五矿集团采购平台

    网站地址:http://ec.mcc.com.cn/b2b/web/two/indexinfoAction.do?actionType=showMoreCgxx&xxposition=cgxx ...

  5. Python爬虫:最牛逼的 selenium爬取方式!

    Python爬虫:最牛逼的 selenium爬取方式! 作为一个男人 在最高光的时刻 这是小编准备的python爬虫学习资料,加群:700341555即可免费获取! Python爬虫:最牛逼的 sel ...

  6. python爬虫--Scrapy框架--Scrapy+selenium实现动态爬取

    python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取 前言 本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行政策文本爬虫进行记录.用于个人爬虫学习记 ...

  7. Python爬虫:运用多线程、IP代理模块爬取百度图片上小姐姐的图片

    Python爬虫:运用多线程.IP代理模块爬取百度图片上小姐姐的图片 1.爬取输入类型的图片数量(用于给用户提示) 使用过百度图片的读者会发现,在搜索栏上输入关键词之后,会显示出搜索的结果,小编想大多 ...

  8. Python爬虫之scrapy框架360全网图片爬取

    Python爬虫之scrapy框架360全网图片爬取 在这里先祝贺大家程序员节快乐,在此我也有一个好消息送给大家,本人已开通了微信公众号,我会把资源放在公众号上,还请大家小手动一动,关注过微信公众号, ...

  9. Python爬虫实例 wallhaven网站高清壁纸爬取。

    文章目录 Python爬虫实例 wallhaven网站高清壁纸爬取 一.数据请求 1.分析网页源码 2.全网页获取 二.数据处理 1.提取原图所在网页链接 2.获取高清图片地址及title 三.下载图 ...

最新文章

  1. [Python设计模式] 第1章 计算器——简单工厂模式
  2. ggplot2箱式图两两比较_作图技巧024篇ggplot2在循环中的坑
  3. java pingpong_面试题。线程pingpong的输出问题
  4. sql怎么撤回update_腾讯SQL“现役运动员”给你的实践小技巧
  5. awk内置字符串函数详解
  6. 给服务器里添加只读用户的脚本
  7. 【概率论】5-9:多项式分布(The Multinomial Distributions)
  8. python运维和开发实战-高级篇
  9. 服务器更换固态后如何安装系统,更换固态硬盘后安装操作系统的两种常用方法...
  10. 论文中sota_CVPR 2020最佳学生论文分享回顾:通过二叉空间分割(BSP)生成紧凑3D网格...
  11. Pixelmator Pro 1.7 Mac版下载
  12. IDEA——问题汇总
  13. c语言的实验题答案,大一C语言上机实验试题及答案
  14. 工业机器人码垛教学实施_《工业机器人码垛工作站安装与调试》教学设计文本.doc...
  15. easyUI之LinkButton(按钮)
  16. 数据中台=大数据平台+数据资产管理平台+数据服务平台
  17. ip反查域名的详细信息(多种方法)
  18. body软件 human_Human body
  19. 计算机毕业设计ssm 课程教学过程f6oz5系统+程序+源码+lw+远程部署
  20. JVM调优(6)新一代的垃圾回收算法

热门文章

  1. proxysql mysql_利用ProxySQL实现MySQL的读写分离
  2. pm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While resolving: undefi
  3. Pyqt5的tableWidget的单元格控件居中
  4. 域名访问和ip访问区别
  5. sublime jsx html插件,Sublime Text3关于react的插件——react语法提示代码格式化
  6. 【网络教程】同花顺公式编辑的基本语法,帮助说明
  7. 基于Matlab绘制自定义边长的正多边形
  8. 电脑开机为什么老是要两次?
  9. 视频缩略图video.js videojs-vtt-thumbnails
  10. 持之以恒,不仅仅是说说而已