在 Python 脚本中执行 curl 命令

我试图在一个 python 脚本中执行 curl 命令。

如果我在航站楼做,看起来是这样的:

curl -X POST -d  '{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto": "ICMP", "actions": "ALLOW", "priority": "10"}' http://localhost:8080/firewall/rules/0000000000000001

我已经看到了使用 pycurl的建议,但是我不知道如何将它应用到我的建议中。

我试着用:

subprocess.call([
'curl',
'-X',
'POST',
'-d',
flow_x,
'http://localhost:8080/firewall/rules/0000000000000001'
])

但是有更好的办法吗?

312624 次浏览

如果您没有对 curl 命令进行过多的调整,也可以直接调用 curl 命令

import shlex
cmd = '''curl -X POST -d  '{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto": "ICMP", "actions": "ALLOW", "priority": "10"}' http://localhost:8080/firewall/rules/0000000000000001'''
args = shlex.split(cmd)
process = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()

你可以像@roippi 说的那样使用 urllib:

import urllib2
data = '{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto": "ICMP", "actions": "ALLOW", "priority": "10"}'
url = 'http://localhost:8080/firewall/rules/0000000000000001'
req = urllib2.Request(url, data, {'Content-Type': 'application/json'})
f = urllib2.urlopen(req)
for x in f:
print(x)
f.close()

Don't!

我知道,这是没有人想要的“答案”。但是如果有什么值得做的事情,做正确的事是值得的,对吗?

这似乎是一个好主意,可能源于一个相当广泛的误解,即像 curl这样的 shell 命令不是程序本身。

所以你要问的是“我如何在我的程序中运行另一个程序,只是为了发出一个微不足道的 Web 请求?”.太疯狂了,肯定有更好的办法,对吧?

Uxio 的回答确实有效。但它看起来不太像 蟒蛇,不是吗?就为了一个小小的请求,就要做这么多工作。蟒蛇应该是关于 飞翔的!任何人写,可能是希望他们只是 callcurl


有用,但有更好的办法吗?

是的,有 一个更好的方式!

请求: 人类的 HTTP

事情不应该是这样的,不应该是巨蟒。

让我们看看这一页:

import requests
res = requests.get('https://stackoverflow.com/questions/26000336')

就是这样,真的! 然后就有了原始的 res.text,或者 res.json()输出,res.headers输出,等等。

你可以看到设置所有选项的详细信息的文档(链接在上面) ,因为我想 OP 现在已经移动了,而你-现在的读者-可能需要不同的选项。

但是,举例来说,它就像这样简单:

url     = 'http://example.tld'
payload = { 'key' : 'val' }
headers = {}
res = requests.post(url, data=payload, headers=headers)

您甚至可以使用一个不错的 Python dict 在带有 params={}的 GET 请求中提供查询字符串。

简单而优雅,保持冷静,继续飞翔。

重新措辞这篇文章中的一个答案,而不是使用 cmd.split ()。尝试使用:

import shlex


args = shlex.split(cmd)

然后将参数提供给子处理。

查查这个文件,了解更多信息: https://docs.python.org/2/library/subprocess.html#popen-constructor

使用这个 工具(宿主 给你免费)将 curl 命令转换为等效的 Python 请求代码:

例如: 这个,

curl 'https://www.example.com/' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' -H 'Origin: https://www.example.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Cookie: SESSID=ABCDEF' --data-binary 'Pathfinder' --compressed

被巧妙地转换为:

import requests


cookies = {
'SESSID': 'ABCDEF',
}


headers = {
'Connection': 'keep-alive',
'Cache-Control': 'max-age=0',
'Origin': 'https://www.example.com',
'Accept-Encoding': 'gzip, deflate, br',
}


data = 'Pathfinder'


response = requests.post('https://www.example.com/', headers=headers, cookies=cookies, data=data)

尝试使用子进程

CurlUrl="curl 'https://www.example.com/' -H 'Connection: keep-alive' -H 'Cache-
Control: max-age=0' -H 'Origin: https://www.example.com' -H 'Accept-Encoding:
gzip, deflate, br' -H 'Cookie: SESSID=ABCDEF' --data-binary 'Pathfinder' --
compressed"

使用 getstatusoutput存储结果

status, output = subprocess.getstatusoutput(CurlUrl)

您可以使用下面的代码段

import shlex
import subprocess
import json


def call_curl(curl):
args = shlex.split(curl)
process = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = process.communicate()
return json.loads(stdout.decode('utf-8'))




if __name__ == '__main__':
curl = '''curl - X
POST - d
'{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto": "ICMP", "actions": "ALLOW", "priority": "10"}'
http: // localhost: 8080 / firewall / rules / 0000000000000001 '''
output = call_curl(curl)
print(output)

subprocess模块内部,还有一个名为 run的选项可以使用它

from subprocess import run
run(curl -X POST -d  '{"nw_src": "10.0.0.1/32", "nw_dst": "10.0.0.2/32", "nw_proto": "ICMP", "actions": "ALLOW", "priority": "10"}' http://localhost:8080/firewall/rules/0000000000000001)