2012-01-29 107 views
0

所以我想開發這個應用程序會從網站獲得驗證碼圖像,並嘗試對其進行解碼等以後我解碼的圖片我可以填補與導致文字驗證碼輸入文本。IronPython的集成.NET

我想用我發現這裏的解決方案:http://www.wausita.com/captcha/ 所以,想在我的主應用程序集成我想它在一個簡單的控制檯應用程序集成之前:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using IronPython.Hosting; 
using Microsoft.Scripting.Hosting; 

namespace Python 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
       var ipy = IronPython.Hosting.Python.CreateRuntime(); 
       dynamic test = ipy.ExecuteFile("crack.py"); 
     } 
    } 
} 

當我運行一個簡單的只需打印「你好」它的工作原理,但是當我跑我的「crack.py」文件我得到以下錯誤test.py文件:

Message: {"Object reference not set to an instance of an object."} 
    Source: "Microsoft.Dynamic" 
    StackTrace: at Microsoft.Scripting.Actions.Calls.MethodCandidate.Caller.Call(Object[] args, Boolean& shouldOptimize) 
    at IronPython.Runtime.Types.BuiltinFunction.BuiltinFunctionCaller`5.Call4(CallSite site, CodeContext context, TFuncType func, T0 arg0, T1 arg1, T2 arg2, T3 arg3) 
    at System.Dynamic.UpdateDelegates.UpdateAndExecute6[T0,T1,T2,T3,T4,T5,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5) 
    at IronPython.Runtime.Importer.Import(CodeContext context, String fullName, PythonTuple from, Int32 level) 
    at IronPython.Runtime.Operations.PythonOps.ImportWithNames(CodeContext context, String fullName, String[] names, Int32 level) 
    at Microsoft.Scripting.Utils.InvokeHelper`5.Invoke(Object arg0, Object arg1, Object arg2, Object arg3) 
    at Microsoft.Scripting.Utils.ReflectedCaller.Invoke(Object[] args) 
    at Microsoft.Scripting.Interpreter.CallInstruction.Run(InterpretedFrame frame) 
    at Microsoft.Scripting.Interpreter.Interpreter.RunInstructions(InterpretedFrame frame) 
    at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame) 
    at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1) 
    at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx) 
    at IronPython.Compiler.PythonScriptCode.Run(Scope scope) 
    at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope) 
    at IronPython.Compiler.RuntimeScriptCode.Run(Scope scope) 
    at Microsoft.Scripting.SourceUnit.Execute(Scope scope, ErrorSink errorSink) 
    at Microsoft.Scripting.SourceUnit.Execute(Scope scope) 
    at Microsoft.Scripting.Hosting.ScriptSource.Execute(ScriptScope scope) 
    at Microsoft.Scripting.Hosting.ScriptEngine.ExecuteFile(String path, ScriptScope scope) 
    at Microsoft.Scripting.Hosting.ScriptEngine.ExecuteFile(String path) 
    at Microsoft.Scripting.Hosting.ScriptRuntime.ExecuteFile(String path) 
    at Python.Program.Main(String[] args) in E:\Python\Python\Program.cs:line 20 

這是crack.py文件

from PIL import Image 
import hashlib 
import time 
import os 
import math 


class VectorCompare: 
    def magnitude(self, concordance): 
    total = 0 
    for word,count in concordance.iteritems(): 
     total += count ** 2 
    return math.sqrt(total) 

    def relation(self, concordance1, concordance2): 
    relevance = 0 
    topvalue = 0 
    for word, count in concordance1.iteritems(): 
     if concordance2.has_key(word): 
     topvalue += count * concordance2[word] 
    return topvalue/(self.magnitude(concordance1) * self.magnitude(concordance2)) 

f = open('workfile.txt', 'w') 

def buildvector(im): 
    d1 = {} 

    count = 0 
    for i in im.getdata(): 
    d1[count] = i 
    count += 1 

    return d1 

v = VectorCompare() 

iconset = ['0','1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] 

imageset = [] 

for letter in iconset: 
    for img in os.listdir('./iconset/%s/' % (letter)): 
    temp = [] 
    if img != "Thumbs.db": # windows check... 
     temp.append(buildvector(Image.open("./iconset/%s/%s" % (letter, img)))) 
    imageset.append({letter:temp}) 

im = Image.open("captcha1.gif") 
im2 = Image.new("P", im.size, 255) 
im = im.convert("P") 
temp = {} 

for x in range(im.size[1]): 
    for y in range(im.size[0]): 
    pix = im.getpixel((y, x)) 
    temp[pix] = pix 
    if pix == 0 or pix == 0: # these are the numbers to get 
     im2.putpixel((y, x), 0) 

inletter = False 
foundletter = False 
start = 0 
end = 0 

letters = [] 

for y in range(im2.size[0]): # slice across 
    for x in range(im2.size[1]): # slice down 
    pix = im2.getpixel((y, x)) 
    if pix != 255: 
     inletter = True 

    if foundletter == False and inletter == True: 
    foundletter = True 
    start = y 

    if foundletter == True and inletter == False: 
    foundletter = False 
    end = y 
    letters.append((start, end)) 

    inletter=False 

count = 0 
for letter in letters: 
    m = hashlib.md5() 
    im3 = im2.crop((letter[0], 0, letter[1], im2.size[1])) 

    guess = [] 

    for image in imageset: 
    for x, y in image.iteritems(): 
     if len(y) != 0: 
     guess.append((v.relation(y[0], buildvector(im3)), x)) 

    guess.sort(reverse=True) 
    print>>f, guess[0] 
    count += 1 

我的問題是:是什麼原因造成這個錯誤,我怎麼能做出蟒蛇電話的工作? 或者,有沒有辦法使用C#替換Python文件「creack.py」的功能?

+2

也許你應該嘗試,直到找到其中的一部分導致錯誤從Python代碼刪除的東西。 – svick 2012-01-29 12:55:18

回答

0

您可以創建一個函數來運行你的IronPythonScript,趕上並重新拋出異常,告訴你什麼行代碼是有問題如下:

public static dynamic RunIronPythonScript(string fileName) 
{ 
    var ipy = IronPython.Hosting.Python.CreateRuntime(); 
    try 
    { 
     dynamic test = ipy.ExecuteFile(fileName); 
     return test; 
    } 
    catch (Exception e) 
    { 
     var engine = IronPython.Hosting.Python.GetEngine(ipy); 
     ExceptionOperations eo = engine.GetService<ExceptionOperations>(); 
     string error = eo.FormatException(e); 
     throw new Exception(error); 
    } 
} 

然後就可以調用它,如下所示:

static void Main(string[] args) 
{ 
    RunIronPythonScript("crack.py"); 
} 

這至少說明你哪一行代碼導致錯誤,使其更容易修復腳本了。

0

嘗試:

Microsoft.Scripting.Hosting.ScriptEngine engine = 
    IronPython.Hosting.Python.CreateEngine(); 

engine.ExecuteFile("crack.py");