comment utiliser python pour exécuter une commande curl

171

Je veux exécuter une commande curl en python.

Habituellement, il me suffit d'entrer la commande dans le terminal et d'appuyer sur la touche Retour. Cependant, je ne sais pas comment cela fonctionne en python.

La commande montre ci-dessous:

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

Il y a un fichier request.json à envoyer pour obtenir une réponse.

J'ai beaucoup cherché et j'étais confus. J'ai essayé d'écrire un morceau de code, même si je ne pouvais pas comprendre complètement. Ça n'a pas marché.

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

Le message d'erreur est «Parse Error». Quelqu'un peut-il me dire comment y remédier? ou comment obtenir une réponse du serveur correctement?

Qiang Fu
la source
1
Pouvez-vous inclure le traçage de l'erreur?
shaktimaan
1
FWIW, avez-vous envisagé d'utiliser pycurl la "liaison Python à cURL" ? Selon vos besoins, il peut être plus efficace / pratique que d'appeler l'utilitaire de ligne de commande en arrière-plan.
Sylvain Leroux
3
Avez-vous besoin d'utiliser cURL? Avez-vous considéré les demandes ? Cela pourrait être plus simple, surtout si vous êtes nouveau sur python, qui a tendance à être impitoyable.
vch
3
ummm python est assez indulgent .... peut-être pas curl
Joran Beasley

Réponses:

191

Par souci de simplicité, vous devriez peut-être envisager d'utiliser la bibliothèque Requests .

Un exemple avec le contenu de la réponse json serait quelque chose comme:

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

Si vous recherchez plus d'informations, dans la section Démarrage rapide , ils ont de nombreux exemples fonctionnels.

ÉDITER:

Pour votre traduction curl spécifique:

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
la source
1
Veuillez @tricknology, essayez de rechercher le bogue et, si vous ne trouvez pas de solution appropriée, postez une nouvelle question.
otorrillas
4
Si quelqu'un d'autre venait à voir cela, la raison pour laquelle cela m'arrivait est que je donnais une chaîne comme charge utile au lieu d'un objet dictionnaire.
tricknology
1
Il semble qu'il y ait une petite faute de frappe dans les en-têtes, qui devrait se lire'Accept-Charset': 'UTF-8'
Stephen Lead
1
Ouvrir le fichier et analyser JSON avant de l'envoyer est inefficace. Vous analysez le JSON puis le reconvertissez en une chaîne avec json.dumps (). C'est une mauvaise réponse.
Nathan K
4
Requestsest une dépendance supplémentaire que vous devez installer et gérer. Pour une solution simple utilisant uniquement la bibliothèque standard, voir stackoverflow.com/a/13921930/111995
geekQ
94

Utilisez simplement ce site Web . Il convertira n'importe quelle commande curl en Python, Node.js, PHP, R ou Go.

Exemple:

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

Devient ceci en 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
la source
3
Pour vous assurer que votre JSON est correctement formaté, importez le module "json" et utilisez json.dumps (payload) sur les données utiles, c'est-à-dire data = json.dumps (data) dans le cas ci-dessus
Richard Bown
23
import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json

peut être?

si vous essayez d'envoyer un fichier

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

ahh merci @LukasGraf maintenant je comprends mieux ce que fait son code original

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
la source
Cela n'inclut pas les données du requests.jsonfichier et ne définit pas l'en- Content-Type: application/jsontête - cela enverra également une GETdemande, pas un fichier POST.
Lukas Graf
1
curl -d @<file>lira les champs à partir desquels publier <file>- ce n'est pas la même chose que le téléchargement de fichiers.
Lukas Graf
@LukasGraf merci :) ... Je n'utilise pas beaucoup curl (lire: presque jamais)
Joran Beasley
Une petite note, data = requests.get(url).jsondevrait êtredata = requests.get(url).json()
dpg5000
en 2014 c'était une propriété maintenant c'est une fonction :) bon appel cependant
Joran Beasley
19
curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

son implémentation python ressemble à

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)

vérifiez ce lien , cela aidera à convertir la commande cURl en python, php et nodejs

cryptoKTM
la source
8

Ma réponse est 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

Je m'excuse de ne pas avoir fourni les paramètres requis parce que c'est confidentiel.

apoorva_bhat
la source
Si vous avez besoin d'utiliser certaines options spéciales de curl comme --resolve, c'est le chemin. Je vous remercie.
nikoskip
comment puis-je obtenir uniquement le json retourné sans la statistique tabulaire
Grant Gubatan
5

Un peu de contexte: je suis allé chercher exactement cette question parce que je devais faire quelque chose pour récupérer du contenu, mais tout ce que j'avais à disposition était une ancienne version de python avec un support SSL inadéquat. Si vous utilisez un MacBook plus ancien, vous savez de quoi je parle. Dans tous les cas, curlfonctionne bien à partir d'un shell (je suppose qu'il a un support SSL moderne lié), donc parfois vous voulez le faire sans utiliser requestsou urllib2.

Vous pouvez utiliser le subprocessmodule pour exécuter curlet accéder au contenu récupéré:

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

Le subprocessmodule de Python 3 contient également .run()un certain nombre d'options utiles. Je vais laisser à quelqu'un qui exécute réellement python 3 le soin de fournir cette réponse.

Joemadeus
la source
-4

Cela pourrait être réalisé avec l'approche de code psuedo mentionnée ci-dessous

Importer les demandes d'importation OS Data = os.execute (URL curl) R = Data.json ()

user9761315
la source
os.system au lieu de os.execute, et les requêtes semblent inutiles dans ce cas
SeanFromIT