como usar python para executar um comando curl

171

Eu quero executar um comando curl em python.

Normalmente, só preciso digitar o comando no terminal e pressionar a tecla Enter. No entanto, não sei como funciona em python.

O comando mostra abaixo:

curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

Há um arquivo request.json a ser enviado para obter resposta.

Eu procurei muito e fiquei confuso. Tentei escrever um pedaço de código, embora não pudesse entender completamente. Não deu certo.

import pycurl
import StringIO

response = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere')
c.setopt(c.WRITEFUNCTION, response.write)
c.setopt(c.HTTPHEADER, ['Content-Type: application/json','Accept-Charset: UTF-8'])
c.setopt(c.POSTFIELDS, '@request.json')
c.perform()
c.close()
print response.getvalue()
response.close()

A mensagem de erro é 'Erro de análise'. Alguém pode me dizer como corrigi-lo? ou como obter resposta do servidor corretamente?

Qiang Fu
fonte
1
Você pode incluir o rastreamento do erro?
precisa saber é
1
FWIW, você considerou usar pycurl o "Python binding to cURL" ? Dependendo de suas necessidades, pode ser mais eficiente / conveniente do que chamar o utilitário de linha de comando nos bastidores.
Sylvain Leroux
3
Você precisa usar cURL? Você já considerou solicitações ? Pode ser mais simples, especialmente se você é novo no python, o que tende a ser implacável.
vch
3
ummm python é muito perdoando .... talvez não onda
Joran Beasley

Respostas:

191

Por uma questão de simplicidade, talvez você deva considerar o uso da biblioteca de solicitações .

Um exemplo com o conteúdo da resposta json seria algo como:

import requests
r = requests.get('https://github.com/timeline.json')
r.json()

Se você procurar mais informações, na seção Início Rápido , eles têm muitos exemplos úteis.

EDITAR:

Para sua tradução específica de curl:

import requests
url = 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere'
payload = open("request.json")
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=payload, headers=headers)
otorrillas
fonte
1
Por favor, @tricknology, tente procurar o bug e, se você não encontrar uma solução adequada, poste uma nova pergunta.
Otorrillas #
4
Caso alguém veja isso, a razão pela qual isso estava acontecendo comigo é que eu estava fornecendo uma string como minha carga útil, em vez de um objeto de dicionário.
tricknology
1
Parece que há um pequeno erro de digitação nos cabeçalhos, que deve ser escrito'Accept-Charset': 'UTF-8'
Stephen Lead
1
Abrir o arquivo e analisar o JSON antes de enviá-lo é desnecessariamente ineficiente. Você analisa o JSON e depois o converte novamente em uma cadeia de caracteres com json.dumps (). Esta é uma resposta ruim.
Nathan K
4
Requestsé uma dependência extra que você precisa instalar e gerenciar. Para uma solução simples usando apenas a biblioteca padrão, consulte stackoverflow.com/a/13921930/111995
geekQ
94

Basta usar este site . Ele converterá qualquer comando curl em Python, Node.js, PHP, R ou Go.

Exemplo:

curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/asdfasdfasdf

Torna-se isso em Python,

import requests

headers = {
    'Content-type': 'application/json',
}

data = '{"text":"Hello, World!"}'

response = requests.post('https://hooks.slack.com/services/asdfasdfasdf', headers=headers, data=data)
Kyle Bridenstine
fonte
3
Para garantir a sua JSON está formatado corretamente importação os "JSON" módulo e o uso json.dumps (payload) sobre a carga de dados ou seja de dados = json.dumps (dados) no caso acima
Richard Bown
23
import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json

talvez?

se você está tentando enviar um arquivo

files = {'request_file': open('request.json', 'rb')}
r = requests.post(url, files=files)
print r.text, print r.json

ahh obrigado @LukasGraf agora entendo melhor o que o código original está fazendo

import requests,json
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
my_json_data = json.load(open("request.json"))
req = requests.post(url,data=my_json_data)
print req.text
print 
print req.json # maybe? 
Joran Beasley
fonte
Isso não inclui dados do requests.jsonarquivo e não define o Content-Type: application/jsoncabeçalho - também, isso enviará uma GETsolicitação, não a POST.
Lukas Graf
1
curl -d @<file>lerá os campos para postar <file>- isso não é o mesmo que o upload do arquivo.
Lukas Graf
@LukasGraf graças :) ... Eu não uso onda muito (leia-se: quase nunca)
Joran Beasley
Uma pequena nota, data = requests.get(url).jsondeve serdata = requests.get(url).json()
dpg5000 28/04
em 2014, era uma propriedade agora é uma função :) boa chamada embora
Joran Beasley
19
curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

sua implementação python seja como

import requests

headers = {
    'Content-Type': 'application/json',
}

params = (
    ('key', 'mykeyhere'),
)

data = open('request.json')
response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search', headers=headers, params=params, data=data)

#NB. Original query string below. It seems impossible to parse and
#reproduce query strings 100% accurately so the one below is given
#in case the reproduced version is not "correct".
# response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere', headers=headers, data=data)

verifique este link , ele ajudará a converter o comando cURl em python, php e nodejs

cryptoKTM
fonte
8

Minha resposta é WRT python 2.6.2.

import commands

status, output = commands.getstatusoutput("curl -H \"Content-Type:application/json\" -k -u (few other parameters required) -X GET https://example.org -s")

print output

Peço desculpas por não fornecer os parâmetros necessários porque é confidencial.

apoorva_bhat
fonte
Se você precisar usar algumas opções especiais de curl como --resolve, este é o caminho. Obrigado.
Nikoskip
Como posso só obter o JSON retornado sem a estatística tabular
Grant Gubatan
5

Alguns antecedentes: procurei exatamente essa pergunta porque precisava fazer algo para recuperar o conteúdo, mas tudo o que tinha disponível era uma versão antiga do python com suporte SSL inadequado. Se você usa um MacBook antigo, sabe do que estou falando. De qualquer forma, curlfunciona bem a partir de um shell (suspeito que tenha um suporte SSL moderno vinculado); portanto, às vezes você deseja fazer isso sem usar requestsou urllib2.

Você pode usar o subprocessmódulo para executar curle obter o conteúdo recuperado:

import subprocess

// 'response' contains a []byte with the retrieved content.
// use '-s' to keep curl quiet while it does its job, but
// it's useful to omit that while you're still writing code
// so you know if curl is working
response = subprocess.check_output(['curl', '-s', baseURL % page_num])

O subprocessmódulo do Python 3 também contém .run()várias opções úteis. Vou deixar para alguém que está realmente executando o python 3 para fornecer essa resposta.

joemadeus
fonte
-4

Isso pode ser alcançado com a abordagem de código psuedo abaixo mencionada

Importar solicitações de importação Dados = os.execute (URL de curvatura) R = Data.json ()

user9761315
fonte
os.system vez de os.execute e solicitações parece desnecessário neste caso
SeanFromIT