Reptile:requests + 云打码平台实现 识别图片验证码登陆

使用requests加上打码平台云打码,实现登陆有图片验证的网站,是图片验证码。

豆瓣的登陆验证方式换了,换成点击验证和图片滑动验证组合的了,所以实验对象不能使用豆瓣了

图片不能是JS写入的,必须得有图片的url,不然没有办法获取验证码图片(我还在学基础的,SO不知道怎么获取js写入的图片)

然后我就想了一个蠢办法,发现在网页里js写入的图片虽然我不能通过xpath获取图片的url但是,但是鼠标放在src上面可以看见图片的URL,我就直接使用了URL,亲测是可以的,但是也只是针对一个网站的,其他的不知道。

# 云打码平台实现验证码登陆流程:
# 1. 对携带验证码的页面数据进行抓取
# 2. 将页面数据中的验证码进行解析,将图片下载到本地
# 3. 将验证码图片提交到云打码平台进行识别,并返回验证码图片上的数据值
# 云打码平台:
# 1. 在官网中进行注册(普通用户和开发者用户都要注册)
# 普通用户用来识别验证码时扣费
# 开发者用户用来获取接口
# 2. 登陆开发者账户:
# 1.示例代码的下载->开发者文档->调用示例及最新DLL->pythonHTTp示例下载
# 2.创建一个软件:->我的软件->添加软件
# 3. 对示例代码的源码进行修改。
云打码平台提供的示例代码更具下面的信息修改就好了:

def getImg(codeImg):
# 用户名(普通用户)
username = '********'

# 密码(普通用户)
password = '*******'

# 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
appid = 6431

# 软件密钥,开发者分成必要参数。登录开发者后台【我的软件】获得!
appkey = '3c8ac0f181871bd22674a631e74d41c8'

# 图片文件
filename = codeImg # 这里是一个变量,存储的是你获取到的图片验证的本地路径

# 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。在此查询所有类型 http://www.yundama.com/price.html 验证码类型列表
codetype = 3000

# 超时时间,秒
timeout = 20

# 检查
if (username == 'username'): # 判断你的参数有没有设置好
print('请设置好相关参数再测试')
else:
# 初始化
yundama = YDMHttp(username, password, appid, appkey) # 实例化YDMHttp类 参数都是上面定义好的

# 登陆云打码
uid = yundama.login();
print('uid: %s' % uid)

# 查询余额
balance = yundama.balance();
print('balance: %s' % balance)

# 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
cid, result = yundama.decode(filename, codetype, timeout);
print('cid: %s, result: %s' % (cid, result))
return result # 返回识别完成的图片验证码值(并不是100%成功,图片的噪点太多,或者其他的因素影响会导致识别不成功)

自己写的代码
name = input('请输入用户名:>>>')
password = input('请输入密码:>>>')

# 访问要登陆的网站并获取验证码图片
img_url = '登陆页面的URL'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/65.0.3325.181 Safari/537.36'
}

page_text = requests.get(url=img_url,headers=headers).text # 对有验证码的登陆页面发起请求,并获取返回数据
# tree = etree.HTML(page_text) # 生成etree对象
codeimg_url = 'http://******/qkonline-pc-provider/captcha-image' # 使用xpath获取图片地址,本来是xpath图片的URL,但是我的这个网址十js写的,我就搞不定了,
# print(codeimg_url) 就用了我自己的办法,鼠标放在src属性上面,然后自己把url写下来。内网地址用****号代替了
code_img = requests.get(url=codeimg_url, headers=headers).content # 对图片发起请求,并获取二进制数据
with open('./img.png', 'wb') as fp:
fp.write(code_img)

codeText = getImg('./img.png') # 将验证码图片提交到云打码平台进行识别,并取得返回的值

# 进行登陆
post_url = 'http://********/qkonline-pc-provider/preLogin?gotoURL=http://*******&client=http://*******&systemTag=eSale'
data = {
'gotoURL': 'http://es.qk365.com',
'client: http':'//es.qk365.com',
'systemTag': 'eSale',
'name': name, # 这个是自己输入的用户名
'password': password, # 这个是自己输入的密码
   'token': codeText # 这个是获取到的图片验证码的值,也就是上面示例代码的返回值,建议给上面写成一个函数
}
# 文件写入
login_text = requests.post(url=post_url,data=data,headers=headers).text
with open('./login.html', 'w', encoding='utf-8') as fp:
fp.write(login_text)
posted @ 2019-01-23 10:06  微雨丶  阅读(825)  评论(0编辑  收藏  举报