Json解析Python子进程

问题描述 投票:1回答:3

这是代码:

inputDomain = subprocess.Popen("cat /etc/localdomains", shell=True,  stdout=subprocess.PIPE)
domains = inputDomain.stdout.read().splitlines()

for domain in domains:
   cmd = "whmapi1 domainuserdata domain " + domain
   output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
   jsonS = json.dumps(output.communicate())
   print json.loads(jsonS)['data']

这里有错误

root @ server [〜/ testP] #python copie.py Traceback(最近一次调用last):文件“copie.py”,第18行,在print json.loads(jsonS)['data'] TypeError:list indices必须是整数,而不是str

这是我需要解析的json的一个例子:

{ 
   "data":{ 
      "userdata":{ 
      "phpopenbasedirprotect":1,
      "options":"ExecCGI Includes",
     "ip":"10.0.0.1",
     "hascgi":"1",
     "group":"user",
     "usecanonicalname":"Off",
     "scriptalias":[ 
        { 
           "url":"/cgi-bin/",
           "path":"/home/user/public_html/cgi-bin"
        },
        { 
           "url":"/cgi-bin/",
           "path":"/home/user/public_html/cgi-bin/"
        }
     ],
     "user":"user",
     "ifmodulemodsuphpc":{ 
        "group":"user"
     },
     "owner":"root",
     "documentroot":"/home/user/public_html",
     "userdirprotect":"",
     "serveralias":"parkeddomain.com www.parkeddomain.com www.example.com",
     "port":"80",
     "homedir":"/home/user",
     "ifmoduleconcurrentphpc":{ 

     },
     "customlog":[ 
        { 
           "target":"/usr/local/apache/domlogs/example.com",
           "format":"combined"
        },
        { 
           "target":"/usr/local/apache/domlogs/example.com-bytes_log",
           "format":"\"%{%s}t %I .\\n%{%s}t %O .\""
        }
     ],
     "servername":"example.com",
     "serveradmin":"[email protected]"
  }
}

所以我需要用户和域名,但python总是回答我需要一个int。谢谢你的帮助。

python json
3个回答
1
投票

因为你的进程返回一个json字符串,所以不需要dump它再次加载它。

# stdout, stderr
jsonS,_ = output.communicate()

现在你有一个字符串,你可以使用json加载

d = json.loads(jsonS)

现在d['data']产生你想要的信息

旁白:正如我所说:

inputDomain = subprocess.Popen("cat /etc/localdomains", shell=True,  stdout=subprocess.PIPE)
domains = inputDomain.stdout.read().splitlines()

可以被原生python取代:

with open("/etc/localdomains") as f: domains = f.read.splitlines()

0
投票

communicate()返回一个元组:(stdoutdata, stderrdata)。当你loads()它回来你得到一个列表,然后尝试使用'data'索引它将失败。例:

import json
import subprocess

cmd = "/bin/date"
output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
jsonS = json.dumps(output.communicate())
print jsonS # ["Fri Feb 10 14:33:42 GMT 2017\n", null]
print json.loads(jsonS)['data'] # TypeError: list indices must be integers, not str

这可能足够了

jsonS = output.communicate()[0]

0
投票

我在Python3下运行上面的代码时遇到了问题,所以这里有一种方法可以实现OP在Python3中的要求

import subprocess
import json


def getProcessOutput(cmd):
    process = subprocess.Popen(
        cmd,
        shell=True,
        stdout=subprocess.PIPE)
    process.wait()
    data, err = process.communicate()
    if process.returncode is 0:
        return data.decode('utf-8')
    else:
        print("Error:", err)
    return ""


for domain in getProcessOutput("cat /etc/localdomains").splitlines():
    cmd = "whmapi1 domainuserdata domain " + domain
    print(json.loads(getProcessOutput(cmd))['data'])

它输出Error: None因为我的机器没有/etc/localdomains但是它似乎工作得很好。

© www.soinside.com 2019 - 2024. All rights reserved.