在Python脚本中执行curl命令


72

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

可以,但是还有更好的方法吗?


1
您不必使用cURL将某些东西发布到服务器上。 requests可以很容易地做到这一点(可以urllib
稍加

选中此更了解在python执行shell CMDS stackoverflow.com/questions/89228/...
Sainath Motlakunta

Answers:


43

您可以像@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()

与子流程相比,urllib2更省时吗?
Kiran Vemuri 2014年

2
它取决于子过程,但是当语言具有核心库来执行操作时,不让子过程调用命令,因此这绝对不是正确的方法
Uxio 2014年

TypeError:POST数据应为字节,字节可迭代或文件对象。它不能是str类型。
穆罕默德·阿什法克

169

别!

我知道,这就是没人想要的“答案”。但是,如果有事值得做,那就值得做对吧?

这似乎是一个好主意,可能是由于人们对shell命令(例如: curl除程序本身以外的任何东西)的。

因此,您要问的是“我如何从我的程序中运行另一个程序,只是发出很少的Web请求?”。太疯狂了,必须有更好的方法吧?

当然,Uxio的答案有效。但这看起来很难像Python一样,对吗?仅需一个小请求,这就是很多工作。Python应该飞了!任何人写作是打心底里希望他们只是call“d curl


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

是的,有一个更好的办法!

请求:HTTP for Humans

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

让我们获取此页面:

import requests
res = requests.get('/programming/26000336')

就是这样,真的!然后res.text,您将获得raw或res.json()输出res.headers,等等。

您可以查看文档(上方链接)以获取有关设置所有选项的详细信息,因为我认为OP现已发展,您-现在的读者-可能需要不同的选项。

但是,例如,它很简单:

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

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

简洁大方。保持冷静,然后继续前进。


我正在使用python 2.4.3。不能使用请求。ImportError:没有名为请求的模块。
加里

11
@Garypip install requests
OJFord

我必须要做json.dumps(payload),但不需要在标头上使用json.dumps方法。
user1045085'9

1
+1。据我所知,使用cURL可以完成的任何事情也可以通过python请求来完成。最好改用那个。
idungotnosn

1
这对于我要寻找的东西非常有效。由于@OJFord
伽罗

30

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

谢谢,我使用
subprocess.call

1
@Ollie Ford的建议对我很有帮助:我已在W10下安装了Requests。从命令行启动Python,然后编写我请求的URL。从现在开始,我将不得不弄清楚如何在.py文件中设置(和查看)流的内容。建议欢迎!
user3722096 '16

25

使用此工具(托管在此处免费)将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)

4
@OJFord启发了我们为什么不在python中使用curl,而Nitin描绘了使用“请求”实现相同效果的最简单方法。我强烈推荐这个答案。
mdabdullah

1
哇哇!这不仅仅是一个“让我为您做”的解决方案。我一直在努力弄清楚即使一切似乎正确,我的命令也无法正常工作的原因。该工具向我指出,我的请求的基本url中包含导致问题的其他参数。对于不熟悉这些要求的人们,此工具非常适合检查此类简单的疏忽。极好的答案。
VanBantam

5

尝试子流程

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)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.