come usare python per eseguire un comando curl


171

Voglio eseguire un comando di arricciatura in Python.

Di solito, ho solo bisogno di inserire il comando nel terminale e premere il tasto Invio. Tuttavia, non so come funziona in Python.

Il comando mostra di seguito:

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

C'è un file request.json da inviare per ottenere la risposta.

Ho cercato molto e mi sono confuso. Ho provato a scrivere un pezzo di codice, anche se non riuscivo a capire appieno. Non ha funzionato

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

Il messaggio di errore è "Errore di analisi". Qualcuno può dirmi come risolverlo? o come ottenere correttamente la risposta dal server?


1
Puoi includere il Traceback dell'errore?
Shaktimaan,


1
FWIW, hai considerato di usare pycurl il "Python binding to cURL" ? A seconda delle esigenze, potrebbe essere più efficiente / conveniente rispetto al richiamo dell'utilità della riga di comando dietro la scena.
Sylvain Leroux,

3
Devi usare cURL? Hai preso in considerazione le richieste ? Potrebbe essere più semplice, soprattutto se non conosci Pitone, il che tende a non perdonare.
VCH

3
ummm python è abbastanza indulgente .... forse non arricciarsi
Joran Beasley il

Risposte:


191

Per semplicità, forse dovresti prendere in considerazione l'uso della libreria Richieste .

Un esempio con contenuto di risposta json potrebbe essere qualcosa del tipo:

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

Se cerchi ulteriori informazioni, nella sezione Quickstart , hanno molti esempi funzionanti.

MODIFICARE:

Per la tua specifica traduzione di arricciatura:

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)

1
Per favore @tricknology, prova a cercare il bug e, se non trovi una soluzione adeguata, pubblica una nuova domanda.
otorrillas,

4
Se dovesse capitare a qualcun altro di vederlo, il motivo per cui ciò mi stava succedendo è che stavo dando una stringa come mio payload invece che un oggetto dizionario.
tricknology il

1
Sembra che ci sia un piccolo errore di battitura nelle intestazioni, che dovrebbe leggere'Accept-Charset': 'UTF-8'
Stephen Lead

1
Aprire il file e analizzare JSON prima di inviarlo è inutilmente inefficiente. Si analizza il JSON e lo si converte nuovamente in una stringa con json.dumps (). Questa è una cattiva risposta
Nathan K,

4
Requestsè una dipendenza aggiuntiva che devi installare e gestire. Per una soluzione semplice utilizzando la libreria standard di solo, vedi stackoverflow.com/a/13921930/111995
geekQ

94

Usa questo sito Web . Converte qualsiasi comando di arricciatura in Python, Node.js, PHP, R o Go.

Esempio:

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

Diventa questo in 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)

3
Per assicurarti che il tuo JSON sia formattato correttamente, importa il modulo "json" e usa json.dumps (payload) sul payload dei dati, ovvero data = json.dumps (data) nel caso precedente
Richard Bown,

23
import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json

può essere?

se stai provando a inviare un file

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

ah grazie @LukasGraf ora capisco meglio cosa sta facendo il suo codice originale

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? 

Ciò non include i dati del requests.jsonfile e non imposta l' Content-Type: application/jsonintestazione - inoltre, invierà una GETrichiesta, non a POST.
Lukas Graf,

1
curl -d @<file>leggerà i campi da cui postare <file>- non è lo stesso del caricamento di file.
Lukas Graf,

@LukasGraf grazie :) ... Non uso molto il ricciolo (leggi: quasi mai)
Joran Beasley

Una piccola nota, data = requests.get(url).jsondovrebbe esseredata = requests.get(url).json()
dpg5000 il

nel 2014 era una proprietà ora è una funzione :) buona chiamata però
Joran Beasley il

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

la sua implementazione di Python è come

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)

controlla questo link , aiuterà a convertire il comando cURl in python, php e nodejs


8

La mia risposta è 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

Mi scuso per non aver fornito i parametri richiesti perché è confidenziale.


Se hai bisogno di usare alcune opzioni speciali da arricciare come --resolve, questo è il modo. Grazie.
nikoskip,

come posso ottenere solo il json restituito senza stat tabulare
Grant Gubatan

5

Alcuni retroscena: ho cercato esattamente questa domanda perché dovevo fare qualcosa per recuperare il contenuto, ma tutto ciò che avevo a disposizione era una vecchia versione di Python con supporto SSL inadeguato. Se utilizzi un MacBook più vecchio, sai di cosa sto parlando. In ogni caso, curlfunziona benissimo da una shell (sospetto che abbia il supporto SSL moderno collegato) quindi a volte vuoi farlo senza usare requestso urllib2.

È possibile utilizzare il subprocessmodulo per eseguire curle ottenere il contenuto recuperato:

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

Il subprocessmodulo di Python 3 contiene anche .run()una serie di utili opzioni. Lascio a qualcuno che sta effettivamente eseguendo python 3 per fornire quella risposta.


-4

Ciò potrebbe essere ottenuto con l'approccio del codice psuedo di seguito indicato

Importa richieste di importazione os Dati = os.execute (curl URL) R = Data.json ()


os.system invece di os.execute, e le richieste sembrano non necessarie in questo caso
SeanFromIT
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.