Python爬虫-验证码处理

在浏览网站的时候,有些网站需要登录,并且登录流程中有验证码验证。在爬虫中带验证的登录通常可以分为4各步骤:

1.获取登录页面:在登陆页面找到登录请求的url以及登录需要提交的参数

2.通过登录页找到验证码的url

3.处理验证码:包括下载验证码,识别验证码

4.发送登录请求:构造登录所需的所有参数进行登录请求

以上的步骤需要在一个session(会话)中进行,否则服务器不能识别验证码。验证码处理的方法一般包括手动处理、图像识别工具处理、云打码等,这次是用到的云打码。就是调用云打码这个网站的一个API将验证码图片传过去,然后获取的返回结果是识别后的验证码字符串。刚好云打码的登录页面需要验证码验证,就拿它做个练习。

获取登录页面

可以在首页看到登录的框,然后输入用户名密码,输入错误的验证码点击登录,在下面的控制台找到登录的请求,可以从请求中占到url,OMG,这里登录请求居然是get发送,而且用户名和密码都没有加密处理,神奇。

到验证码的url

跟上面类似的操作,刷新一下验证码可以在下面找到对应的获取验证码的请求,插葱header中拿到对应的验证码图片的url

处理验证码

接下来就是处理验证码了,需要用到云打码的一个接口,去他的网站上将Python对应的工具下载下来,备用。然后发送请求将验证码下载下来,调用接口将图片串过去获取返回的验证码。

发送登录请求

构造参数齐全的登录请求,从第一部中可以看到登录需要传递4各参数,username,password,utype,code

分别对应用户名、密码、用户类型、验证码。

最后请求返回结果:{"ret":0,"msg":"登录成功}

代码

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# @File  : VerifyCodeDemo.py

# @Author: Small-orange

# @Date  : 2020-1-9

# @Desc  : 登录验证码破解

#步骤:1.找到登陆页面  2.获取验证码  3.处理验证码  4.发送登录请求

import requests

from fake_useragentimport UserAgent

from VerifiyCode.VerifyCodeUtilimport get_code

def parserCode(url,session):

# 获取验证码图片

    filename ='verify_code.png'  # 验证码图片的文件名

    r = session.get(img_url,headers=headers)

if r.status_code ==200:

with open(filename,'wb')as f:#保存验证码图片

            f.write(r.content)

vrify_code = get_code(filename)

return vrify_code

def login(url,vrify_code,session):

pass

    #发送登录请求

    params = {

"username":"small_orange",

"password":"small_orange",

"utype":"1",

"vcode":vrify_code

}

res = session.get(url,headers=headers,params=params)

if res.status_code ==200:

res.encoding ='utf-8'

        print(res.text)

return res.text

if __name__ =='__main__':

img_url ='http://www.yundama.com/index/captcha'

    url ='http://www.yundama.com/index/login'

    ua = UserAgent()

headers = {'User-Agent':ua.chrome}

#获取session,保证获取验证码到登录在一个会话内完成

    session = requests.session()

code = parserCode(img_url,session)

ret_text = login(url,code,session)

工具类

import http.client, mimetypes, urllib, json, time, requests

class YDMHttp:

apiurl ='http://api.yundama.com/api.php'

    def __init__(self, username, password, appid, appkey):

self.username = username

self.password = password

self.appid =str(appid)

self.appkey = appkey

def request(self, fields, files=[]):

response =self.post_url(self.apiurl, fields, files)

response = json.loads(response)

return response

def balance(self):

data = {'method':'balance','username':self.username,'password':self.password,'appid':self.appid,'appkey':self.appkey}

response =self.request(data)

if (response):

if (response['ret']and response['ret'] <0):

return response['ret']

else:

return response['balance']

else:

return -9001

    def login(self):

data = {'method':'login','username':self.username,'password':self.password,'appid':self.appid,'appkey':self.appkey}

response =self.request(data)

if (response):

if (response['ret']and response['ret'] <0):

return response['ret']

else:

return response['uid']

else:

return -9001

    def upload(self, filename, codetype, timeout):

data = {'method':'upload','username':self.username,'password':self.password,'appid':self.appid,'appkey':self.appkey,'codetype':str(codetype),'timeout':str(timeout)}

file = {'file': filename}

response =self.request(data, file)

if (response):

if (response['ret']and response['ret'] <0):

return response['ret']

else:

return response['cid']

else:

return -9001

    def result(self, cid):

data = {'method':'result','username':self.username,'password':self.password,'appid':self.appid,'appkey':self.appkey,'cid':str(cid)}

response =self.request(data)

return responseand response['text']or ''

    def decode(self, filename, codetype, timeout):

cid =self.upload(filename, codetype, timeout)

if (cid >0):

for iin range(0, timeout):

result =self.result(cid)

if (result !=''):

return cid, result

else:

time.sleep(1)

return -3003,''

        else:

return cid,''

    def report(self, cid):

data = {'method':'report','username':self.username,'password':self.password,'appid':self.appid,'appkey':self.appkey,'cid':str(cid),'flag':'0'}

response =self.request(data)

if (response):

return response['ret']

else:

return -9001

    def post_url(self, url, fields, files=[]):

for keyin files:

files[key] =open(files[key],'rb');

res = requests.post(url,files=files,data=fields)

return res.text

def get_code(filename):

# 用户名

    username    ='small_orange'

    # 密码

    password    ='small_orange'

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

    appid      =9871

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

    appkey      ='f835940ba51bac771996d70df6531bce'

    # 图片文件

    filename    = filename

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

    codetype    =1005

    # 超时时间,秒

    timeout    =60

    # 检查

    if (username =='username'):

print('请设置好相关参数再测试')

else:

# 初始化

        yundama = YDMHttp(username, password, appid, appkey)

# 登陆云打码

        uid = yundama.login();

# 查询余额

        balance = yundama.balance();

# 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果

        cid, result = yundama.decode(filename, codetype, timeout);

print('cid: %s, result: %s' % (cid, result))

return result

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 经过多次尝试,模拟登录淘宝终于成功了,实在是不容易,淘宝的登录加密和验证太复杂了,煞费苦心,在此写出来和大家一起分...
    追不到的那缕风阅读 5,636评论 0 3
  • 我们可以借助插件来做 打开插件,找到自己需要的验证码 筛选有用的路径 把对应的视图函数也拿过来,注意还需要一个ge...
    程序员之路阅读 5,161评论 0 1
  • 本文主要讲述官方提供的客户端以及自己写的增删查改工具: ros_tool.py功能总汇,展示界面用了python的...
    追寻823阅读 8,563评论 0 1
  • 搜狗 Passport iOS SDK 是搜狗为开发者提供的第三方单点登录和搜狗账户注册登录服务。本版本提供的第三...
    Www刘阅读 6,893评论 2 1
  • 常用模块 认识模块 什么是模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文...
    go以恒阅读 6,213评论 0 6

友情链接更多精彩内容