百度ocr进行验证码识别,然后模拟登录一个高校的某一网站,最终的验证码识别出来了,但模拟登录没有成功。过了一天,又学习了一下, 发现是两次登陆时的cookie不一致导致的,把这个解决之后,模拟登陆才成功,这里记录一下整个过程
注意,程序里面出现的涉及path,password,username,Access_Key,Secret_Key等信息的需要自行替换
本来想用pytesseract进行文字识别,但是经过好几次尝试都因为安装速度太慢导致安装失败。后面在网上看这个东西直接进行文字识别效果不太好,需要后面进行训练,就暂时选择了放弃。后面就用了百度文字识别。
百度文字识别文档,根据这个高精度文字识别写的baidu_ocr_accurate_basic.py
,如下:
baidu_ocr_accurate_basic.py
# encoding:utf-8
import requests
import base64
import json
# 获取access_token
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials' \
'&client_id=Access_Key&client_secret=Secret_Key'
rsp = requests.get(url=host).json()
access_token = rsp['access_token']
'''
通用文字识别(高精度版)
'''
# 二进制方式打开图片文件
def verify_text(image_path):
request_url = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic"
f = open(image_path, 'rb')
img = base64.b64encode(f.read())
f.close()
params = {"image":img}
request_url = request_url + "?access_token=" + access_token
headers = {'content-type': 'application/x-www-form-urlencoded'}
response = requests.post(request_url, data=params, headers=headers).text
result_json = json.loads(response)
text = ''
for words_result in result_json["words_result"]:
text = text + words_result["words"]
return text
- 另一种文字识别的接口——超级鹰
chaojiying.py
#!/usr/bin/env python
# coding:utf-8
import requests
from hashlib import md5
class Chaojiying_Client(object):
def __init__(self, username, password, soft_id):
self.username = username
password = password.encode('utf8')
self.password = md5(password).hexdigest()
self.soft_id = soft_id
self.base_params = {
'user': self.username,
'pass2': self.password,
'softid': self.soft_id,
}
self.headers = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
def PostPic(self, im, codetype):
"""
im: 图片字节
codetype: 题目类型 参考 http://www.chaojiying.com/price.html
"""
params = {
'codetype': codetype,
}
params.update(self.base_params)
files = {'userfile': ('ccc.jpg', im)}
r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
return r.json()
def ReportError(self, im_id):
"""
im_id:报错题目的图片ID
"""
params = {
'id': im_id,
}
params.update(self.base_params)
r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
return r.json()
def verify_text(image_path):
chaojiying = Chaojiying_Client('username', 'password', '软件ID')
# im = open('job_cqu_verify.png', 'rb').read()
# wtf
im = open(image_path, 'rb').read()
text = chaojiying.PostPic(im, 1902)['pic_str']
print('text:', text)
return text
simulate_login.py
import requests
from lxml import etree
# from spider_basic.expand.chaojiying import verify_text
from spider_basic.expand.baidu_ocr_accurate_basic import verify_text
# 创建session对象
session = requests.Session()
url_login = 'http://job.cqu.edu.cn/user/login?callback=login'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36'
}
# 获取验证码图片
rsp = session.get(url=url_login, headers=headers).text
tree = etree.HTML(rsp)
image_src = 'http://job.cqu.edu.cn' + tree.xpath('//*[@id="verifyCodeImage"]/@src')[0]
image_content = session.get(url=image_src, headers=headers).content
image_path = './job_cqu_verify.png'
with open(image_path, 'wb') as f:
f.write(image_content)
# 调用百度ocr接口进行验证码识别
verify_data = verify_text(image_path)
verify_code = ''
for i in verify_data:
if i != ' ':
verify_code += i
# 进行模拟登录
data = {
'username': '',
'university': '',
'loginType': 'normal',
'password': '',
'verifyCode': verify_code,
'loginsubmit': '1',
}
print('verify_data: {} 长度为{}'.format(verify_data, len(verify_data)))
print('verify_code: {} 长度为{}'.format(verify_code, len(verify_code)))
# rsp_simulate = requests.get(url=url_login, data=data, headers=headers)
#注意这里的请求方式
rsp_simulate = session.post(url=url_login, data=data, headers=headers)
print('status:', rsp_simulate.status_code)
with open('./success_login.html', 'w', encoding='utf-8') as f:
f.write(rsp_simulate.text)
结果
-
控制台运行结果
-
浏览器打开结果
-
不过由于这个网站还有别的反模拟登录措施,过一会儿页面就会显示
不过管他的,反正是模拟登陆上了
过程记录
- image_src 没有加前面的部分
- 模拟登录时的请求方法应该为post,而不是get
- 这里的
baidu_ocr_accurate_basic.py
很坑的一点是它返回的验证码常常会多一两个空格,这个过了好久才注意到, - 这个简单的文字识别竟然不能识别验证码里面有线条的
- 如果在程序中没有创建session对象的话,浏览器打开就会出现验证码不正确。因为验证码的请求会返回一个cookie,所以需要创建session对象,利用session发起请求的话会把把返回的cookie自动加载进去。