python版 —— 驗證碼校正 打碼兔平台的使用介紹__python

來源:互聯網
上載者:User
python版 —— 驗證碼校正 打碼兔平台的使用介紹 1. 背景

驗證碼(CAPTCHA)的全稱是全自動區分電腦和人類的圖靈測試(Completely Automated Public Turing Test to tell Computers and Humans Apart),是一種用於區分人與電腦Bot的挑戰應答系統測試。CAPTCHA可通過設定一些人類很容易執行而Bot很難完成的任務來區分人類和Bot。
CAPTCHA經常被用來阻止Bot使用部落格來影響搜尋引擎排名、簽署電子郵箱帳戶發送垃圾郵件或參與網上投票等。
通常,CAPTCHA是一個輕微扭曲的字母數字字元影像檔,人通常可以很容易讀取映像中的字元。而Bot能夠識別該內容包含一個映像,但不知道是什麼映像。考慮到弱視群體,一些CAPTCHA使用音頻檔案。在這樣一個系統中,人可以聽到一個字母或短句並打出他所聽到的,從而證明他不是Bot。 一般來說,自動化處理驗證碼有兩種方式:
光學字元辨識(Optical Character Recognition, OCR),從映像中抽取文本。主要的庫有pytesser,tesseract。一般來說,對於複雜的驗證碼映像,需要先修改驗證碼映像,去除其中的背景雜音,只保留文本部分,再送入庫中進行解析。而且識別率不是很高,想提高識別率,需要通過長時間機器學習的訓練,代價較大。而且對於極其複雜的驗證碼,OCR甚至無法使用。 使用驗證碼處理服務(藉助於專業的打碼平台)。付費調用他們提供的API。當把驗證碼圖片傳給他們的API時,會有人進行人工查看,並在HTTP響應中給出解析後的常值內容。一般來說,整個解析過程在10s(打碼兔平台),最長60s,而且價位不高,1元 = 50~100個驗證碼(根據驗證碼類型進行收費)。如果驗證碼不多,為了提高識別效率和簡化操作,就可以選擇這種方式。 2. 環境 python 3.6.1 系統:win7 IDE:pycharm 安裝過chrome瀏覽器 配置好chromedriver selenium 3.7.0 3. 打碼兔平台的使用流程 3.1. 原理 將驗證碼圖片,打碼平台帳號,密碼等按照指定格式調用API(訪問URL),得到返回的結果。 打碼兔平台地址:http://www.dama2.com/ 打碼兔平台開發人員文檔:http://wiki.dama2.com/index.php 3.2. 流程

第一步:註冊一個開發人員帳號

第二步:產生使用驗證碼的軟體的ID和key
登入開發人員帳號,進入 我的軟體,點擊建立軟體,填好資料提交就會產生一個軟體key的。

備忘: 把你的軟體key填進相應的代碼參數裡面,然後把軟體key發給打碼兔的線上客服,他會幫你釋放保留,你就可以用帳號test,密碼test測試了。 如圖所示,這就是軟體ID,軟體名稱,軟體KEY,都是程式會用到的參數。 當別人使用你的軟體ID和軟體Key進行驗證碼消費時,作為軟體的開發人員是能拿到分成的。這也是搶票軟體的賺錢的方式之一。也就是說,開發人員帳號用於軟體開發,賺錢。 軟體不需要公開。而且開發人員帳號不能進行付費打碼。

第三步:註冊一個普通使用者的帳號,並進行儲值,用這個帳號進行付費打碼。
也就是說,開發人員帳號用於賺錢,普通使用者帳號用於付費打碼 4. 自訂方法 原始文檔請參考官網:http://wiki.dama2.com/index.php?n=ApiDoc.Http

# 對打碼兔平台提供的代碼進行了一些改動,更加適應本軟體的需求import hashlibimport urllib.requestimport urllibimport jsonimport base64import requests# md5加密字串def md5str(str):    m = hashlib.md5(str.encode(encoding="utf-8"))    return m.hexdigest()# md5加密bytedef md5(byte):    m = hashlib.md5(byte)    return m.hexdigest()# 打碼兔API類class DamatuApi():    # 關聯的開發人員帳號    # 此帳號關聯的驗證碼類型,預設是1~8位隨機英文和數字組合    ID = '51773'  # 開發人員帳號 軟體的AppID    KEY = 'fbfb9022a1499b0c6436f223f98b714e'  # 開發人員帳號 軟體的key,   我的軟體 產生的Key    # 打碼平台host    HOST = 'http://api.dama2.com:7766/app/'    def __init__(self, username, password, limitCount):        self.username = username        self.password = password        # 限制每個執行個體請求驗證碼的次數,防止意外,導致請求驗證碼過多,消費不可控        self.limitCount = limitCount        # 用於統計驗證碼請求次數        self.count = 0    # 計算使用者簽名,按照一定的規則對 key和userName 進行加密    def getSign(self, param=b''):        return (md5(bytes(self.KEY, encoding="utf8") + bytes(self.username, encoding="utf8") + param))[:8]    # 獲得加密後的密鑰 key , userName, password    def getPwd(self):        return md5str(self.KEY + md5str(md5str(self.username) + md5str(self.password)))    # 向打碼平台提交請求    def post(self, urlPath, formData = {}):        '''        :param urlPath: 用於構造url,向不同的地址請求不同的資料        :param formData: 提交的資料        :return:        '''        url = self.HOST + urlPath        try:            response = requests.request(method='post',                                        url=url,                                        data=formData,                                        timeout=60                                        )            print(f"text = {response.text}")            # 餘額,balance, text = {"ret":0,"balance":"9957","sign":"2428e5f9"}            # 驗證碼,captcha, text = {"ret":0,"id":558899326,"result":"230876","sign":"8d55bdb1"}            return response.text        except Exception as e:            print(f"postRequest error. exception = {e}, urlPath = {urlPath}, formData = {formData}")            return {"ret": -1}    # 查詢餘額 return 是正數為餘額, 如果為負數 則為錯誤碼    def getBalance(self):        data = {            'appID': self.ID,            'user': self.username,            'pwd': self.getPwd(),            'sign': self.getSign()        }        res = self.post('d2Balance', data)        jres = json.loads(res)        if jres['ret'] == 0:            return (True, jres['balance'])        else:            return (False, jres['ret'])    # 上傳驗證碼圖片    def decode(self, filePath, type):        '''        :param filePath:  驗證碼圖片路徑 如d:/1.jpg        :param type: 驗證碼類型,查看http://wiki.dama2.com/index.php?n=ApiDoc.Pricedesc        :return: 元組,result[0] = True為成功,False為錯誤碼        '''        if self.count >= self.limitCount:            print(f"decode: 請求驗證碼數量超過限制自訂數量。")            return (False, False)        # 拿到驗證碼圖片的資料        f = open(filePath, 'rb')        fdata = f.read()        filedata = base64.b64encode(fdata)        f.close()        data = {            'appID': self.ID,            'user': self.username,            'pwd': self.getPwd(),            'type': type,            'fileDataBase64': filedata,            'sign': self.getSign(fdata)        }        res = self.post('d2File', data)        jres = json.loads(res)        self.count += 1        if jres['ret'] == 0:            # 注意這個json裡面有ret,id,result,cookie,根據自己的需要擷取            return (True, jres['result'])        else:            return (False, jres['ret'])    # url地址打碼,提供驗證碼連結    def decodeUrl(self, url, type):        '''        :param url: 驗證碼地址        :param type: 驗證碼類型 http://wiki.dama2.com/index.php?n=ApiDoc.Pricedesc        :return: 元組,result[0] = True為成功,False為錯誤碼        '''        if self.count >= self.limitCount:            print(f"decodeUrl: 請求驗證碼數量超過限制自訂數量。")            return (False, False)        data = {            'appID': self.ID,            'user': self.username,            'pwd': self.getPwd(),            'type': type,            'url': urllib.parse.quote(url),            'sign': self.getSign(url.encode(encoding="utf-8"))        }        res = self.post('d2Url', data)        jres = json.loads(res)        self.count += 1        if jres['ret'] == 0:            # 注意這個json裡面有ret,id,result,cookie,根據自己的需要擷取            return (True, jres['result'])        else:            return (False, jres['ret'])    # 報錯,暫時先不關心。 參數id(string類型)由上傳打碼函數的結果獲得 return 0為成功 其他見錯誤碼    def reportError(self, id):        data = {            'appID': self.ID,            'user': self.username,            'pwd': self.getPwd(),            'id': id,            'sign': self.getSign(id.encode(encoding="utf-8"))        }        res = self.post('d2ReportError', data)        res = str(res, encoding="utf-8")        jres = json.loads(res)        return jres['ret']
5. 內嵌程式碼中使用

驗證碼截圖,請參考文章:http://blog.csdn.net/zwq912318834/article/details/78605486 第一步,確保餘額充足

# 打碼兔API類 執行個體化,參數是打碼兔使用者帳號和密碼. 最後一個是限制驗證碼的次數,防止出故障時,無限刷驗證碼,消費過大# dmt=DamatuApi("test","test")# 目前本軟體驗證碼定位為: 1~8位元字英文混搭, 題分21分dmt = DamatuApi("ancode", "ancode2017", 200)# 先查看餘額是否充足# BalanceRes = (True, '9931')balanceRes = dmt.getBalance()   # 查詢餘額if balanceRes[0] == True and int(balanceRes[1]) > 0:    # 餘額充足, 可以放心爬取    print(f"main: balanceRes = {balanceRes}")    # 開始爬取資料    #......
第二步,驗證碼校正。
檢測驗證碼是否出現。 對驗證碼進行截圖。 發送驗證碼圖片進行解碼。 向網站提交驗證碼解析結果。 檢測驗證碼是否校正成功。 注意:每一次頁面的變動,都可能讓之前擷取的元素失焦,需要重新擷取。
# 部分代碼# 通過Image處理映像,截取驗證碼圖片imgCaptcha.save('clawerImgs/captcha.png')# 將驗證碼送往打碼兔進行解碼# codeRes = (True, 'FMAE')# 56 代表驗證碼類型,1~8位元字英文組合# 參考:http://wiki.dama2.com/index.php?n=ApiDoc.PricedescdamatuRes = DamatuInstance.decode('clawerImgs/captcha.png', 56)while(damatuRes[0] == False):    if damatuRes[1] == False:        raise Exception(f"打碼兔超出自訂最大限制數,終止軟體. damatuRes = {damatuRes}")    else:        # 驗證碼請求失敗,查詢下餘額,看是否充足        balanceRes = DamatuInstance.getBalance()        if balanceRes[0] == True and int(balanceRes[1]) > 0:            damatuRes = DamatuInstance.decode('clawerImgs/captcha.png', 56)            time.sleep(2)        else:            # 打碼兔 餘額不足, 拋出異常,終止軟體            raise Exception(f"打碼兔餘額不足,或者超出自訂最大限制數,終止軟體. balanceRes = {balanceRes}")# 點擊提交按鈕input = browser.find_element_by_xpath("//div[@class='input']/input[@id='J_CodeInput']")input.clear()input.send_keys(damatuRes[1])print(f"發送驗證碼為: damatuRes = {damatuRes}")time.sleep(3)# 提交submit = browser.find_element_by_xpath("//button[@id='J_submit']")submit.click()time.sleep(5)################################################# 處理完,提交完驗證碼之後,迴歸到首頁面,繼續抓取商品browser.switch_to.default_content()time.sleep(2)browser.refresh()   # 處理完之後進行頁面重新整理time.sleep(5)# 然後重新檢測驗證碼是否存在,如果還在就迴圈重複處理,如果不在,下面這個流程也不會繼續captchaHandler(browser, DamatuInstance)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.