python下調用pytesseract識別某網站驗證碼

来源:http://www.cnblogs.com/zhongtang/archive/2016/06/06/5560361.html
-Advertisement-
Play Games

一、pytesseract介紹 1、pytesseract說明 pytesseract最新版本0.1.6,網址:https://pypi.python.org/pypi/pytesseract Python-tesseract is a wrapper for google's Tesseract- ...


一、pytesseract介紹

1、pytesseract說明

pytesseract最新版本0.1.6,網址:https://pypi.python.org/pypi/pytesseract

Python-tesseract is a wrapper for google's Tesseract-OCR
( http://code.google.com/p/tesseract-ocr/ ). It is also useful as a
stand-alone invocation script to tesseract, as it can read all image types
supported by the Python Imaging Library, including jpeg, png, gif, bmp, tiff,
and others, whereas tesseract-ocr by default only supports tiff and bmp.
Additionally, if used as a script, Python-tesseract will print the recognized
text in stead of writing it to a file. Support for confidence estimates and
bounding box data is planned for future releases.

翻譯一下大意:

a、Python-tesseract是一個基於google's Tesseract-OCR的獨立封裝包;

b、Python-tesseract功能是識別圖片文件中文字,並作為返回參數返回識別結果;

c、Python-tesseract預設支持tiff、bmp格式圖片,只有在安裝PIL之後,才能支持jpeg、gif、png等其他圖片格式;

2、pytesseract安裝

INSTALLATION:

Prerequisites:
* Python-tesseract requires python 2.5 or later or python 3.
* You will need the Python Imaging Library (PIL). Under Debian/Ubuntu, this is
the package "python-imaging" or "python3-imaging" for python3.
* Install google tesseract-ocr from http://code.google.com/p/tesseract-ocr/ .
You must be able to invoke the tesseract command as "tesseract". If this
isn't the case, for example because tesseract isn't in your PATH, you will
have to change the "tesseract_cmd" variable at the top of 'tesseract.py'.
Under Debian/Ubuntu you can use the package "tesseract-ocr".

Installing via pip: 
See the [pytesseract package page](https://pypi.python.org/pypi/pytesseract) 
```
$> sudo pip install pytesseract 

 翻譯一下:

a、Python-tesseract支持python2.5及更高版本;

b、Python-tesseract需要安裝PIL(Python Imaging Library) ,來支持更多的圖片格式;

c、Python-tesseract需要安裝tesseract-ocr安裝包,具體參看上一篇博文

 

綜上,Pytesseract原理:

1、上一篇博文中提到,執行命令行 tesseract.exe 1.png output -l eng ,可以識別1.png中文字,並把識別結果輸出到output.txt中;

2、Pytesseract對上述過程進行了二次封裝,自動調用tesseract.exe,並讀取output.txt文件的內容,作為函數的返回值進行返回。

二、pytesseract使用

 USAGE:
```
> try:
> import Image
> except ImportError:
> from PIL import Image
> import pytesseract
> print(pytesseract.image_to_string(Image.open('test.png')))
> print(pytesseract.image_to_string(Image.open('test-european.jpg'), lang='fra'))

 

可以看到:

1、核心代碼就是image_to_string函數,該函數還支持-l eng 參數,支持-psm 參數。

 

用法:
image_to_string(Image.open('test.png'),lang="eng" config="-psm 7")

2、pytesseract里調用了image,所以才需要PIL,其實tesseract.exe本身是支持jpeg、png等圖片格式的。

 

實例代碼,識別某公共網站的驗證碼(大家千萬別幹壞事啊,思慮再三,最後還是隱掉網站功能變數名稱,大家去找別的網站試試吧……):

#-*-coding=utf-8-*-
__author__='zhongtang'

import urllib
import urllib2
import cookielib
import math
import random
import time
import os
import htmltool
from pytesseract import *
from PIL import Image
from PIL import ImageEnhance
import re

class orclnypcg:
    def __init__(self):
        self.baseUrl='http://jbywcg.****.com.cn'
        self.ht=htmltool.htmltool()
        self.curPath=self.ht.getPyFileDir()
        self.authCode=''
        
    def initUrllib2(self):
        try:
            cookie = cookielib.CookieJar()
            cookieHandLer = urllib2.HTTPCookieProcessor(cookie)
            httpHandLer=urllib2.HTTPHandler(debuglevel=0)
            httpsHandLer=urllib2.HTTPSHandler(debuglevel=0)
        except:
            raise
        else:
             opener = urllib2.build_opener(cookieHandLer,httpHandLer,httpsHandLer)
             opener.addheaders = [('User-Agent','Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11')]
             urllib2.install_opener(opener)
             
    def urllib2Navigate(self,url,data={}):           #定義連接函數,有超時重連功能
        tryTimes = 0
        while True:
            if (tryTimes>20):
                print u"多次嘗試仍無法鏈接網路,程式終止"
                break
            try:
                if (data=={}):
                    req = urllib2.Request(url)
                else:
                    req = urllib2.Request(url,urllib.urlencode(data))
                response =urllib2.urlopen(req)
                bodydata = response.read()
                headerdata = response.info()
                if headerdata.get('Content-Encoding')=='gzip':
                    rdata = StringIO.StringIO(bodydata)
                    gz = gzip.GzipFile(fileobj=rdata)
                    bodydata = gz.read()
                    gz.close()
                tryTimes = tryTimes +1
            except urllib2.HTTPError, e:
              print 'HTTPError[%s]\n' %e.code                
            except urllib2.URLError, e:
              print 'URLError[%s]\n' %e.reason    
            except socket.error:
                print u"連接失敗,嘗試重新連接"
            else:
                break
        return bodydata,headerdata
    
    def randomCodeOcr(self,filename):
        image = Image.open(filename)
        #使用ImageEnhance可以增強圖片的識別率
        #enhancer = ImageEnhance.Contrast(image)
        #enhancer = enhancer.enhance(4)
        image = image.convert('L')
        ltext = ''
        ltext= image_to_string(image)
        #去掉非法字元,只保留字母數字
        ltext=re.sub("\W", "", ltext)
        print u'[%s]識別到驗證碼:[%s]!!!' %(filename,ltext)
        image.save(filename)
        #print ltext
        return ltext

    def getRandomCode(self):
        #開始獲取驗證碼
        #http://jbywcg.****.com.cn/CommonPage/Code.aspx?0.9409255818463862
        i = 0 
        while ( i<=100):
            i += 1 
            #拼接驗證碼Url
            randomUrlNew='%s/CommonPage/Code.aspx?%s' %(self.baseUrl,random.random())
            #拼接驗證碼本地文件名
            filename= '%s.png' %(i)
            filename=  os.path.join(self.curPath,filename)
            jpgdata,jpgheader = self.urllib2Navigate(randomUrlNew)
            if len(jpgdata)<= 0 :
                print u'獲取驗證碼出錯!\n'
                return False
            f = open(filename, 'wb')
            f.write(jpgdata)
            #print u"保存圖片:",fileName
            f.close()
            self.authCode = self.randomCodeOcr(filename)


#主程式開始
orcln=orclnypcg()
orcln.initUrllib2()
orcln.getRandomCode()
View Code

 

三、pytesseract代碼優化

上述程式在windows平臺運行時,會發現有黑色的控制台視窗一閃而過的畫面,不太友好。

略微修改了pytesseract.py(C:\Python27\Lib\site-packages\pytesseract目錄下),把上述過程進行了隱藏。

# modified by zhongtang hide console window
# new code
IS_WIN32 = 'win32' in str(sys.platform).lower()
if IS_WIN32:
   startupinfo = subprocess.STARTUPINFO()
   startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
   startupinfo.wShowWindow = subprocess.SW_HIDE
   proc = subprocess.Popen(command,
        stderr=subprocess.PIPE,startupinfo=startupinfo)
'''
# old code
proc = subprocess.Popen(command,
   stderr=subprocess.PIPE)
'''
# modified end

為了方便初學者,把pytesseract.py也貼出來,高手自行忽略。

#!/usr/bin/env python
'''
Python-tesseract is an optical character recognition (OCR) tool for python.
That is, it will recognize and "read" the text embedded in images.

Python-tesseract is a wrapper for google's Tesseract-OCR
( http://code.google.com/p/tesseract-ocr/ ).  It is also useful as a
stand-alone invocation script to tesseract, as it can read all image types
supported by the Python Imaging Library, including jpeg, png, gif, bmp, tiff,
and others, whereas tesseract-ocr by default only supports tiff and bmp.
Additionally, if used as a script, Python-tesseract will print the recognized
text in stead of writing it to a file. Support for confidence estimates and
bounding box data is planned for future releases.


USAGE:
```
 > try:
 >     import Image
 > except ImportError:
 >     from PIL import Image
 > import pytesseract
 > print(pytesseract.image_to_string(Image.open('test.png')))
 > print(pytesseract.image_to_string(Image.open('test-european.jpg'), lang='fra'))
```

INSTALLATION:

Prerequisites:
* Python-tesseract requires python 2.5 or later or python 3.
* You will need the Python Imaging Library (PIL).  Under Debian/Ubuntu, this is
  the package "python-imaging" or "python3-imaging" for python3.
* Install google tesseract-ocr from http://code.google.com/p/tesseract-ocr/ .
  You must be able to invoke the tesseract command as "tesseract". If this
  isn't the case, for example because tesseract isn't in your PATH, you will
  have to change the "tesseract_cmd" variable at the top of 'tesseract.py'.
  Under Debian/Ubuntu you can use the package "tesseract-ocr".
  
Installing via pip:   
See the [pytesseract package page](https://pypi.python.org/pypi/pytesseract)     
$> sudo pip install pytesseract   

Installing from source:   
$> git clone [email protected]:madmaze/pytesseract.git   
$> sudo python setup.py install    


LICENSE:
Python-tesseract is released under the GPL v3.

CONTRIBUTERS:
- Originally written by [Samuel Hoffstaetter](https://github.com/hoffstaetter) 
- [Juarez Bochi](https://github.com/jbochi)
- [Matthias Lee](https://github.com/madmaze)
- [Lars Kistner](https://github.com/Sr4l)

'''

# CHANGE THIS IF TESSERACT IS NOT IN YOUR PATH, OR IS NAMED DIFFERENTLY
tesseract_cmd = 'tesseract'

try:
    import Image
except ImportError:
    from PIL import Image
import subprocess
import sys
import tempfile
import os
import shlex

__all__ = ['image_to_string']

def run_tesseract(input_filename, output_filename_base, lang=None, boxes=False, config=None):
    '''
    runs the command:
        `tesseract_cmd` `input_filename` `output_filename_base`
    
    returns the exit status of tesseract, as well as tesseract's stderr output

    '''
    command = [tesseract_cmd, input_filename, output_filename_base]
    
    if lang is not None:
        command += ['-l', lang]

    if boxes:
        command += ['batch.nochop', 'makebox']
        
    if config:
        command += shlex.split(config)
        
    # modified by zhongtang  hide console window
    # new code
    IS_WIN32 = 'win32' in str(sys.platform).lower()
    if IS_WIN32:
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        startupinfo.wShowWindow = subprocess.SW_HIDE
    proc = subprocess.Popen(command,
            stderr=subprocess.PIPE,startupinfo=startupinfo)
    '''
    # old code
    proc = subprocess.Popen(command,
            stderr=subprocess.PIPE)
    '''
    # modified end
    
    return (proc.wait(), proc.stderr.read())

def cleanup(filename):
    ''' tries to remove the given filename. Ignores non-existent files '''
    try:
        os.remove(filename)
    except OSError:
        pass

def get_errors(error_string):
    '''
    returns all lines in the error_string that start with the string "error"

    '''

    lines = error_string.splitlines()
    error_lines = tuple(line for line in lines if line.find('Error') >= 0)
    if len(error_lines) > 0:
        return '\n'.join(error_lines)
    else:
        return error_string.strip()

def tempnam():
    ''' returns a temporary file-name '''
    tmpfile = tempfile.NamedTemporaryFile(prefix="tess_")
    return tmpfile.name

class TesseractError(Exception):
    def __init__(self, status, message):
        self.status = status
        self.message = message
        self.args = (status, message)

def image_to_string(image, lang=None, boxes=False, config=None):
    '''
    Runs tesseract on the specified image. First, the image is written to disk,
    and then the tesseract command is run on the image. Resseract's result is
    read, and the temporary files are erased.
    
    also supports boxes and config.
    
    if boxes=True
        "batch.nochop makebox" gets added to the tesseract call
    if config is set, the config gets appended to the command.
        ex: config="-psm 6"

    '''

    if len(image.split()) == 4:
        # In case we have 4 channels, lets discard the Alpha.
        # Kind of a hack, should fix in the future some time.
        r, g, b, a = image.split()
        image = Image.merge("RGB", (r, g, b))
    
    input_file_name = '%s.bmp' % tempnam()
    output_file_name_base = tempnam()
    if not boxes:
        output_file_name = '%s.txt' % output_file_name_base
    else:
        output_file_name = '%s.box' % output_file_name_base
    try:
        image.save(input_file_name)
        status, error_string = run_tesseract(input_file_name,
                                             output_file_name_base,
                                             lang=lang,
                                             boxes=boxes,
                                             config=config)
        if status:
            #print 'test' , status,error_string
            errors = get_errors(error_string)
            raise TesseractError(status, errors)
        f = open(output_file_name)
        try:
            return f.read().strip()
        finally:
            f.close()
    finally:
        cleanup(input_file_name)
        cleanup(output_file_name)

def main():
    if len(sys.argv) == 2:
        filename = sys.argv[1]
        try:
            image = Image.open(filename)
            if len(image.split()) == 4:
                # In case we have 4 channels, lets discard the Alpha.
                # Kind of a hack, should fix in the future some time.
                r, g, b, a = image.split()
                image = Image.merge("RGB", (r, g, b))
        except IOError:
            sys.stderr.write('ERROR: Could not open file "%s"\n' % filename)
            exit(1)
        print(image_to_string(image))
    elif len(sys.argv) == 4 and sys.argv[1] == '-l':
        lang = sys.argv[2]
        filename = sys.argv[3]
        try:
            image = Image.open(filename)
        except IOError:
            sys.stderr.write('ERROR: Could not open file "%s"\n' % filename)
            exit(1)
        print(image_to_string(image, lang=lang))
    else:
        sys.stderr.write('Usage: python pytesseract.py [-l language] input_file\n')
        exit(2)

if __name__ == '__main__':
    main()
View Code

以上……


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在項目中遇到了一個比較奇怪的問題,在foreach迴圈中修改列表的值後沒有生效,後面使用時還是獲取列表時的值,原因是因為使用了 yield return 。下麵讓我們來探究下其中的原因: 首先來看下 yield return 官方的解釋 使用 yield return 語句可一次返回一個元素。通過 ...
  • 在很多時候,我們在資料庫裡面定義表欄位和實際在頁面中展示的內容,往往是不太匹配的,頁面數據可能是多個表數據的綜合體,因此除了我們在表設計的時候考慮周到外,還需要考慮數據展現的處理。如果是常規的處理,那麼需要對部分外鍵欄位進行特別的轉義處理,如果需要增加多一些欄位,那麼這種處理可能就相對比較麻煩一些。... ...
  • 一、存儲過程與函數的區別: 1.一般來說,存儲過程實現的功能要複雜一點,而函數的實現的功能針對性比較強。 2.對於存儲過程來說可以返回參數(output),而函數只能返回值或者表對象。 3.存儲過程一般是作為一個獨立的部分來執行,而函數可以作為查詢語句的一個部分來調用,由於函數可以返回一個表對象,因 ...
  • XML(可擴展標記語言)文件,可以用來標記數據、定義數據類型,是一種允許用戶對自己的標記語言進行定義的源語言。 XML與HTML的設計區別是:XML 被設計為傳輸和存儲數據,其焦點是數據的內容。而HTML 被設計用來顯示數據,其焦點是數據的外觀。HTML 旨在顯示信息,而 XML 旨在傳輸信息。 X ...
  • 本文內容 實例化一個類的方式 用 New 關鍵字實例化一個類 用 Activator 實例化一個類 用 Assembly 實例化一個類 性能比較 環境 比較 分析 代碼 在開發應用程式時,能夠動態實例化一個類很有用。給出類的一個字元串名稱,就能夠創建這個類的一個實例。若這些需要實例化的類都繼承同一個 ...
  • 示例: 參數一為構件樹的數據集合,參數二為樹節點轉化委托,參數三為根節點選擇器,參數四是父子關係選擇器. ...
  • 介紹一種新類型查詢方法,類似linq,lambda語法,類似標準的sql使用習慣,支持匿名類型,泛型,目前支持mssql,mysql, 切換隻需要DatabaseConfig.DatabaseType = DatabaseType.SQLServer;無需改任何代碼,dll後續開放下載 使用說明:基 ...
  • 單例模式 單例模式是許多開發人員最先接觸到的模式之一,可以認為就是一個全局變數。它的初始化過程無非就是一開始就是創建一個實例,或者延遲初始化等需要用到的時候創建一個實例。這裡需要註意的是多線程情況下創建一個實例,通常需要加鎖(Lock)來解決問題。這裡我們可以利用C 的系統函數Interlocked ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...