我正在尝试在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'
])
它有效,但还有更好的方法吗?
答案 0 :(得分:131)
我知道,那是"答案"没有人想要。但是,如果值得做某事,值得做正确,对吧?
这看起来像一个好主意可能源于一个相当广泛的误解,即curl
之类的shell命令不是程序本身。
所以你要问的是"我如何从我的程序中运行这个其他程序,只是为了做一个微不足道的小网页请求?"。那太疯狂了,还有更好的方法吗?
Uxio's answer确实有效。但它看起来很难 Pythonic ,是吗?这只是为了一个小小的请求而做了很多工作。 Python应该是关于flying的!任何写作的人都可能希望他们只是call
' d curl
!
它有效,但有更好的方法吗?
事情不应该是这样的。不是在Python中。
让我们来看看这个页面:
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请求中提供查询字符串。
简单而优雅。保持冷静,然后继续飞行。
答案 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)