繁体   English   中英

IronPython与C#/ .NET的集成

[英]IronPython integration with C#/ .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");
        }
    }
}

当我运行带有打印“ Hello”的简单test.py文件时,它可以工作,但是当我运行“ crack.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

我的问题是:是什么导致此错误,如何使python调用正常工作? 或者,是否可以使用C#替换Python文件“ creack.py”功能?

您可以创建一个函数来运行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");
 }

这至少会向您显示导致错误的代码行,从而更容易修复脚本。

尝试:

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

engine.ExecuteFile("crack.py");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM