机器学习识别验证码与百度莱茨狗

最近很火的百度莱茨狗想必大家都有接触。不知道大家都有几只史诗狗了?
0x01 领狗
莱茨狗4只狗免费领取地址分享
领取地址1:https://pet-chain.baidu.com/chain/splash
领取地址2:https://pet-chain.baidu.com/chain/splash?appId=2&tpl=wallet
领取地址3:https://pet-chain.baidu.com/chain/splash?appId=3&tpl=wallet
领取地址4:https://pet-chain.baidu.com/chain/splash?appId=4&tpl=wallet

不过我昨天只领到了两只。

0x02 刷市场买便宜狗

# -*- coding: utf-8 -*-
import requests
import json
import time

headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36',
    'Content-Type': 'application/json',
    'Cookie': '',  # Cookie替换成自己的. 
    'Origin': 'https://pet-chain.baidu.com',
    'Referer': 'https://pet-chain.baidu.com/chain/dogMarket'
    }

class pet_chain:
    def getInfo(petId):  #获取宠物信息
        url = "https://pet-chain.baidu.com/data/pet/queryPetByIdWithAuth"
        data = json.dumps({"petId":petId,"requestId":1517813967221,"appId":1,"tpl":""})
        req = requests.post(url, headers=headers, data=data)
        text = json.loads(req.content)
        #print text['data']['userName']
        #print text['data']['id']
        #print text['data']['rareDegree']
        #print text['data']['amount']
        #print text['data']['ethAddr']
        return {'userName':text['data']['userName'],'id':text['data']['id'],'rareDegree':text['data']['rareDegree'],'amount':text['data']['amount'],'ethAddr':text['data']['ethAddr'] }

    def buy(self,petId): #购买宠物
        url = 'https://pet-chain.baidu.com/data/txn/create'
        data = json.dumps({"petId":petId,"requestId":1517818584013,"appId":1,"tpl":""})
        req = requests.post(url, headers=headers, data=data)
        print req.content


    def getMarket(self): #搜索市场
        url = 'https://pet-chain.baidu.com/data/market/queryPetsOnSale'
        data = json.dumps({"pageNo":2,"pageSize":2000,"querySortType":"AMOUNT_ASC","petIds":[]}) #按价钱从低到高排序。每页2000只狗。
        req = requests.post(url, headers=headers, data=data)
        text = json.loads(req.content)
        for pet in text['data']['petsOnSale']:
            if(pet['rareDegree'] > 1):  #只要卓越以上的
                #print pet
                print '品种:' , pet['rareDegree']  #0 - 5 分别为 普通,优秀,卓越, 史诗  后面的没见过。
                print '价钱:' , pet['amount']
                print 'id:' , pet['id']
                print 'petId:' , pet['petId']

                #self.buy(pet['petId']) #是否自动购买。


if __name__ == '__main__':
    w = pet_chain()
    #w.buy('1858371085567322557')  #调用购买

    w.getMarket() # 市场查询

通过这个脚本可以买到便宜的狗。但是后来百度对市场进行了限制。
1、每页只能显示20只狗
2、买狗需要验证码

0x03 基于SVM的机器学习识别验证码

1、批量获取验证码

# -*- coding: utf-8 -*-
import requests
import json
import base64
import time

headers = {
    'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Mobile Safari/537.36',
    'Content-Type': 'application/json',
    'Cookie':XXX,
    'Origin': 'https://pet-chain.baidu.com',
    'Referer': 'https://pet-chain.baidu.com/chain/dogMarket'
    }

class captcha:
    def __init__(self):
        return

    def getCaptcha(self):
        url = 'https://pet-chain.baidu.com/data/captcha/gen'
        data = json.dumps({"requestId":1517879979928,"appId":1,"tpl":""})
        req = requests.post(url, headers=headers, data=data, timeout=2)
        return json.loads(req.content)['data']['img']

        
if __name__=='__main__':
    w = captcha()
# 批量抓取样本
    while 1:
        imgdata = ''
        try:
            img = w.getCaptcha()
        except:
            pass
        imgdata = base64.b64decode(img)  
        file = open('img/' + str(time.time()) + '.jpg','wb')  
        file.write(imgdata)  
        file.close()

2、打码
我手动打的,根据验证码内容把图片改成 ADTF.jpg

3、机器学习

# -*- coding: utf-8 -*-
import os
import cv2
import time
import joblib
import numpy as np
from PIL import Image
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
from sklearn.svm import SVC

class learn:
    def __init__(self):
        self.goodCaseDir = './img/good/' #这里放打完码的图片
        self.learnJobDir = './img/job/'
        self.noneDir = './img/none/' #这里是没打码的图片
        return

    def makeCase(self):
        files = os.listdir(self.goodCaseDir)
        for name in files:
            im = Image.open(self.goodCaseDir + name)
            im1 = im.crop((50,10,97,80))
            im2 = im.crop((95,10,144,80))
            im3 = im.crop((142,10,188,80))
            im4 = im.crop((185,10,235,80))
            txt = name.split('.')[0]
            im1.save(self.learnJobDir + txt[0]+str(time.time())+'.jpg')
            im2.save(self.learnJobDir + txt[1]+str(time.time())+'.jpg')
            im3.save(self.learnJobDir + txt[2]+str(time.time())+'.jpg')
            im4.save(self.learnJobDir + txt[3]+str(time.time())+'.jpg')

    def extractLetters(self,path):
        x = []
        y = []
        files = os.listdir(self.learnJobDir)
        for name in files:
            x.append(self.getletter(self.learnJobDir + name))
            y.append(name[0].lower())
        return x, y

    def getletter(self,fn):
        fnimg = cv2.imread(fn)  # 读取图像
        img = cv2.resize(fnimg, (100, 100))  # 将图像大小调整
        alltz = []
        for now_h in range(0, 100):
            xtz = []
            for now_w in range(0, 100):
                b = img[now_h, now_w, 0]
                g = img[now_h, now_w, 1]
                r = img[now_h, now_w, 2]
                btz = 255 - b
                gtz = 255 - g
                rtz = 255 - r
                if btz > 0 or gtz > 0 or rtz > 0:
                    nowtz = 1
                else:
                    nowtz = 0
                xtz.append(nowtz)
            alltz += xtz
        return alltz
            
    def trainSVM(self):
        array = self.extractLetters(self.learnJobDir)
        #print array
        letterSVM = SVC(kernel="linear",C=1).fit(array[0], array[1])
        joblib.dump(letterSVM, 'letter.pkl')

    def ocrImg(self,fileName):
        clf = joblib.load('letter.pkl')
        img = Image.open(fileName)
        data = self.getletter(fileName)
        data = np.array([data])
        #print(data)
        oneLetter = clf.predict(data)[0]
        return oneLetter

    def run(self):
        files = os.listdir(self.noneDir)
        for name in files:
            im = Image.open(self.noneDir + name)
            im.show()
            im1 = im.crop((50,10,97,80))
            im2 = im.crop((95,10,144,80))
            im3 = im.crop((142,10,188,80))
            im4 = im.crop((185,10,235,80))
            txt = name.split('.')[0]
            im1.save('./img/tmp/1.jpg')
            im2.save('./img/tmp/2.jpg')
            im3.save('./img/tmp/3.jpg')
            im4.save('./img/tmp/4.jpg')
            tmpfiles = os.listdir('./img/tmp/')
            for tmpfile in tmpfiles:
                print self.ocrImg('./img/tmp/' + tmpfile)
            raw_input()

    def main(self,im):
        im1 = im.crop((50,10,97,80))
        im2 = im.crop((95,10,144,80))
        im3 = im.crop((142,10,188,80))
        im4 = im.crop((185,10,235,80))

        im1.save('./img/tmp/1.jpg')
        im2.save('./img/tmp/2.jpg')
        im3.save('./img/tmp/3.jpg')
        im4.save('./img/tmp/4.jpg')
        tmpfiles = os.listdir('./img/tmp/')
        vcode = []
        for tmpfile in tmpfiles:
             vcode.append(self.ocrImg('./img/tmp/' + tmpfile))
        return ''.join(vcode)

        
    
if __name__ == '__main__':
    w = learn()
    print '开始对正样本切图.....'
    #w.makeCase()
    print '样本切图完成,开始进行学习建模.....'
    #w.trainSVM()
    print '建模完成'
    #w.ocrImg('./img/3.jpg')
    print '开始识别验证码'
    #w.run()
    im = Image.open('code.jpg')
    print w.main(im)

0x04 再次刷狗
整合一下,这次只发部分代码


    def buy(self,petId,validCode):
        cap_url = 'https://pet-chain.baidu.com/data/captcha/gen'
        data = json.dumps({"requestId":1517889037133,"appId":1,"tpl":""})
        req = requests.post(cap_url, headers=headers, data=data, timeout=2)
        img = json.loads(req.content)['data']['img']
        image_string = cStringIO.StringIO(base64.b64decode(img))
        im = Image.open(image_string)
        captcha = q.main(im)
        print captcha
        url = 'https://pet-chain.baidu.com/data/txn/create'
        data = json.dumps({"petId":petId,"captcha":captcha,"validCode":validCode,"requestId":1517888890852,"appId":1,"tpl":""})
        req = requests.post(url, headers=headers, data=data, timeout=2)
        print json.loads(req.content)['errorMsg']
        print req.content


    def getMarket(self,page):
        url = 'https://pet-chain.baidu.com/data/market/queryPetsOnSale'
        i = 1
        while i <= page:
            print i
            try:
                data = json.dumps({"pageNo":page,"pageSize":1,"querySortType":"AMOUNT_ASC","petIds":[],"requestId":1517887362977,"appId":1,"tpl":""})
                req = requests.post(url, headers=headers, data=data, timeout=5)
                #print req.content
                text = json.loads(req.content)

                for pet in text['data']['petsOnSale']:
                    if(pet['rareDegree'] >= 0):# and float(pet['amount']) <= 1800) :
                        print pet
                        print '品种:' , pet['rareDegree']
                        print '价钱:' , pet['amount']
                        print 'id:' , pet['id']
                        print 'petId:' , pet['petId']
                i += 1
            except:
                pass
                time.sleep(2)
        return {'petId': pet['petId'],'validCode': pet['validCode']}

最后我刷到了两只史诗狗、三只卓越狗。希望大家也能有所收获。【技术上的!】

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

推荐阅读更多精彩内容

  • 今天,我又听说了一起压力型自杀事件。 91年的大学生,在面对职场和人际关系的问题中压力无法消解,最终选择了跳楼。 ...
    耳羽荷阅读 425评论 0 1
  • “行走,是生命对世界的探寻,是人生对生命的一种追求。” 路漫漫,天空时常笼罩着不知是晨雾还是雾霾,铭子迈步...
    桥梁纽带阅读 484评论 0 1
  • 一直以来喜欢码字,喜怒哀乐都喜欢用文字去表达。有时候写些东西,并不是为了给人看,只是写给内心的独白。 生命的年轮,...
    老骥的纪阅读 647评论 0 0
  • 2016年阳春三月,离我的生日只有三个月,而距离最后一次见到你却已三年有余。我所在的城市有春天清浅的风,风...
    崔崔崔酒九阅读 645评论 0 4