在Python脚本中执行curl命令

时间:2014-09-23 16:40:00

标签: python python-2.7 curl pycurl

我正在尝试在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'
])

它有效,但还有更好的方法吗?

7 个答案:

答案 0 :(得分:131)

唐'!吨

我知道,那是"答案"没有人想要。但是,如果值得做某事,值得做正确,对吧?

这看起来像一个好主意可能源于一个相当广泛的误解,即curl之类的shell命令不是程序本身。

所以你要问的是"我如何从我的程序中运行这个其他程序,只是为了做一个微不足道的小网页请求?"。那太疯狂了,还有更好的方法吗?

Uxio's answer确实有效。但它看起来很难 Pythonic ,是吗?这只是为了一个小小的请求而做了很多工作。 Python应该是关于flying的!任何写作的人都可能希望他们只是call' d curl

  

它有效,但有更好的方法吗?

是的,更好的方式!

Requests: HTTP for Humans

  

事情不应该是这样的。不是在Python中。

让我们来看看这个页面:

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

真的,真的!然后,您将获得原始res.textres.json()输出,res.headers等。

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

但是,例如,它很简单:

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

您甚至可以使用漂亮的Python dict在params={}的GET请求中提供查询字符串。

简单而优雅。保持冷静,然后继续飞行。

答案 1 :(得分:29)

你可以使用urllib作为@roippi说:

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()

答案 2 :(得分:20)

如果你没有过多调整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()

答案 3 :(得分:5)

使用此tool(免费托管here)将curl命令转换为等效的Python请求代码:

示例:这个

curl 'https://www.example.com/' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0' -H 'Origin: https://www.libib.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.libib.com',
    'Accept-Encoding': 'gzip, deflate, br',
}

data = 'Pathfinder'

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

答案 4 :(得分:4)

尝试子流程

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)

答案 5 :(得分:0)

重述本文中的答案之一,而不是使用cmd.split()。尝试使用:

import shlex

args = shlex.split(cmd)

然后将args送入subprocess.Popen。

查看此文档以获取更多信息:https://docs.python.org/2/library/subprocess.html#popen-constructor

答案 6 :(得分:0)

您可以使用以下代码片段

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)
相关问题