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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,695评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,569评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,130评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,648评论 1 297
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,655评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,268评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,835评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,740评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,286评论 1 318
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,375评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,505评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,185评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,873评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,357评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,466评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,921评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,515评论 2 359

推荐阅读更多精彩内容

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