【问题标题】:Python code not executingPython代码未执行
【发布时间】:2012-02-22 09:55:15
【问题描述】:

我有以下从命令行执行的代码:

import cgi,time,os,json,sys,zipfile,urllib2
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from time import strftime
from poster.encode import multipart_encode, MultipartParam
from poster.streaminghttp import register_openers

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):
        try:
            if self.path.endswith("/"):
                self.send_response(200)
                self.send_header('Content-type',    'text/html')
                self.end_headers()
                self.wfile.write("<HTML> GET OK.<BR>")
                return  
            return

        except IOError:
            self.send_error(404,'File Not Found: %s' % self.path)


    def do_POST(self):
        global rootnode
        ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
        if ctype == 'multipart/form-data':
            query=cgi.parse_multipart(self.rfile, pdict)
        self.send_response(200)
        self.send_header('Content-type',    'text/html')
        self.end_headers()
        file = query.get('file')

        zfile = "C:\Users\VM1\Desktop\data.zip"
        extract_path = "C:\Users\VM1\Desktop\data\\"

        f = open(zfile, "wb")
        f.write(file[0])
        f.close()
        self.wfile.write("POST OK. File received from VM Host")
        print("File received from VM Host.")
        print("Unzipping zip file")
        unzip = zipfile.ZipFile(zfile)
        unzip.extractall(extract_path)
        print "Files extracted to " + extract_path
        scan_path = '"C:\Program Files (x86)\AVG\AVG2012\\avgscana.exe" /repok /report=C:\Users\VM1\Desktop\\avg_scan_results.txt /scan=' + extract_path
        os.system('"%s"' % scan_path)
        self.write_json_report()
        self.upload_json_report()
        return

    def write_json_report(self):
        scan_results = open("avg_scan_results.txt", "r")
        saved = sys.stdout
        f = file('avg_report.json', 'wb')
        sys.stdout = f
        dict2 = {}
        for line in scan_results:
            if ".jpg" in line:
                result = line.split('\\')
                result_split = result[5].split(' ')
                filename = result_split[0]
                raw_status = result_split[3]
                if "OK" in raw_status:
                    status = "Okay"
                    status_code = "0"
                elif "Virus identified" in raw_status:
                    status = raw_status
                    status_code = "1"
                dict2[filename] = {'FileName': filename, 'DateTime': strftime("%Y-%m-%d %H:%M:%S"), 'statusCode': status_code, 'Description': status}
        print json.dumps(dict2)
        sys.stdout = saved
        f.close()
        print ""
        print "JSON report written"
        json_zip = zipfile.ZipFile("avg_report.zip", "w")
        try:
            json_zip.write('avg_report.json')
        finally:
            json_zip.close()
        return

    def upload_json_report(self):
        av_name = "AVG Free 2012"
        av_version = ""
        scan_results = open("avg_scan_results.txt", "r")
        for line in scan_results:
            if "Program version" in line:
                version_split = line.split(', ')
                program_version_full = version_split[0]
                program_version_split = program_version_full.split(' ')
                av_version = program_version_split[2]
        register_openers()
        datagen, headers = multipart_encode({"av_name": av_name, "av_version": av_version, "filename": "avg_report.zip", "content": open("avg_report.zip", "rb")})
        request = urllib2.Request("http://" + self.client_address[0] + ":8080/", datagen, headers)
        print "Uploading JSON report"
        print urllib2.urlopen(request).read()
        return

def main():
    try:
        server = HTTPServer(('', 8080), MyHandler)
        print 'Server started..'
        server.serve_forever()
    except KeyboardInterrupt:
        print 'KeyboardInterrupt received, shutting down server'
        server.socket.close()

if __name__ == '__main__':
    main()

upload_json_report() 外,其余功能都运行良好。字符串Uploading JSON report 显示,但后面的行不执行。我正在侦听请求的服务器没有收到任何内容。这里的代码有什么问题吗?如果是,问题是什么,我该如何解决?非常感谢。

编辑: 我已经使用该方法中的以下几行创建了一个单独的客户端:

register_openers()
datagen, headers = multipart_encode({"av_name": av_name, "av_version": av_version, "filename": "avg_report.zip", "content": open("avg_report.zip", "rb")})
request = urllib2.Request("http://" + self.client_address[0] + ":8080/", datagen, headers)
print "Uploading JSON report"
print urllib2.urlopen(request).read()

这行得通。我很困惑为什么相同的代码行不能在函数中工作。

【问题讨论】:

  • 你确定 urllib2 工作正常吗?在 python 解释器上试试这个,看看它是否工作。 >>> 导入 urllib2 >>> 响应 = urllib2.urlopen("google.com")
  • 我的 urllib2 肯定可以工作,因为我从 register_openers() 开始复制并粘贴代码并且它工作了
  • 发布的代码不是有效的 Python(例如,请参阅第 12-18 行的缩进)。我不想改变它,因为我不确定原文是什么,它改变了意思
  • 那是我的格式错误,我已经编辑过了
  • 很好 - 但仍然有一个错误(缩进的第二个返回行)

标签: python http-post


【解决方案1】:

BaseHTTPRequestHandler 维护一个单线程(和单进程)服务器。这意味着每个请求都必须先完成执行,然后才能执行另一个请求。

upload_json_report 函数是从 do_POST 方法中调用的。在它运行时,您的服务器无法处理其他任何事情。但随后在行:

    print urllib2.urlopen(request).read()

您实际上是在尝试将 .zip 文件上传到同一端口,即 8080。 因此,upload_json_report 正在等待 do_POST 完成,而 do_POST 正在等待 @987654328 @完成,所以他们当然永远不会停止等待。

顺便说一下,这解释了为什么它在您的服务器上工作(我假设它是多线程的,尽管您需要提供更多详细信息),以及为什么当您使用单独的执行它时它可以工作客户端(它不会等待自己完成)。

【讨论】:

  • 我明白了。我有一台服务器,它使用与这个相同的结构运行。有没有办法让它成为多线程?
  • 一方面,我不确定您为什么要让该服务器有效地将文件上传到自身。还是将其发送给客户端?
  • 这段代码放在一个虚拟机中,它会在收到客户端的文件后将文件上传到虚拟机主机服务器。
  • 虚拟机与主机服务器在不同的机器上?问题是他们最终是否都会使用端口 8080。另外,为什么不使用现有的服务器,例如带有 mod_python 的 apache?
  • VM 与主机服务器在同一台机器上。我使用上面的代码是因为我想要一个轻量级的解决方案。但我会在 Apache 上用 mod_python 试一试,看看效果如何。谢谢你的建议
【解决方案2】:

我建议调试代码。为此,我将删除 print 语句,在 urllib2.urlopen 方法调用之前添加 pdb.set_trace 并运行脚本。一旦调试器接管,我会检查 url 是否是您期望的,尝试执行下一行并检查 urllib2.urlopen 返回的值是什么(响应代码、文本等)。这应该可以为您提供有关正在发生的事情的足够信息,并希望让您知道如何解决问题。

【讨论】:

  • 感谢您的回答!我会试试看,然后给大家更新一下
  • 如何检查网址?我已经尝试过,但无法打印出任何 url
  • @androidnoob 在调试器中,p request.get_full_url() 应该打印生成的 url。
  • 它只打印出我的服务器的ip地址,没有变量,我猜它不是POST编码的。但奇怪的是,它在我的服务器上工作,但不是这个..
【解决方案3】:

urllib2.urlopen(...) 返回一个文件描述符对象,您必须读取该对象才能打印出响应。本质上,为了查看它从服务器获得的响应,您需要执行print urllib2.urlopen(request).read()

【讨论】:

  • 我试过了,但是代码仍然没有执行,我的服务器也没有收到任何 POST 请求
【解决方案4】:

我的建议是在“urllib2.urlopen”行周围添加“try”“except”,看看是否引发了任何异常。

try:
    request = urllib2.Request("http://" + self.client_address[0] + ":8080/", datagen, headers)
except Exception, e:
    print e

有了打印出来的异常信息,你可能会有一些线索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-09
    • 2014-06-29
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多