jak używać Pythona do wykonywania polecenia curl

171

Chcę wykonać polecenie curl w Pythonie.

Zwykle wystarczy wpisać polecenie w terminalu i nacisnąć klawisz powrotu. Jednak nie wiem, jak to działa w Pythonie.

Polecenie pokazuje poniżej:

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

W celu uzyskania odpowiedzi należy wysłać plik request.json.

Szukałem dużo i pomyliłem się. Próbowałem napisać kawałek kodu, chociaż nie mogłem w pełni go zrozumieć. To nie zadziałało.

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

Komunikat o błędzie to „Błąd analizy”. Czy ktoś może mi powiedzieć, jak to naprawić? lub jak poprawnie uzyskać odpowiedź od serwera?

Qiang Fu
źródło
1
Czy możesz dołączyć Traceback błędu?
shaktimaan,
1
FWIW, czy rozważałeś użycie pycurl jako "powiązanie Pythona z cURL" ? W zależności od potrzeb może być bardziej wydajne / wygodne niż wywoływanie narzędzia wiersza poleceń za kulisami.
Sylvain Leroux
3
Czy musisz używać cURL? Czy rozważałeś wnioski ? Może być prostsze, zwłaszcza jeśli dopiero zaczynasz przygodę z Pythonem, który zwykle jest bezlitosny.
vch
3
ummm Python jest całkiem wyrozumiały ... może nie zwija się
Joran Beasley

Odpowiedzi:

191

Dla uproszczenia może warto rozważyć użycie biblioteki Requests .

Przykład z treścią odpowiedzi json wyglądałby tak:

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

Jeśli szukasz dalszych informacji, w sekcji Szybki start zawierają one wiele praktycznych przykładów.

EDYTOWAĆ:

Dla twojego konkretnego tłumaczenia 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
źródło
1
Proszę @tricknology, spróbuj wyszukać błąd, a jeśli nie znajdziesz odpowiedniego rozwiązania, zadaj nowe pytanie.
otorrillas
4
Gdyby ktoś inny to zobaczył, powodem, dla którego tak się dzieje, jest to, że jako ładunek zamiast obiektu słownika podawałem ciąg znaków.
tricknology
1
Wygląda na to, że w nagłówkach jest mała literówka, która powinna brzmieć'Accept-Charset': 'UTF-8'
Stephen Lead
1
Otwieranie pliku i analizowanie JSON przed wysłaniem jest niepotrzebnie nieefektywne. Analizujesz kod JSON, a następnie konwertujesz go z powrotem na ciąg za pomocą json.dumps (). To zła odpowiedź.
Nathan K
4
Requeststo dodatkowa zależność, którą musisz zainstalować i zarządzać. Aby zapoznać się z prostym rozwiązaniem wykorzystującym tylko standardową bibliotekę, zobacz stackoverflow.com/a/13921930/111995
geekQ
93

Po prostu skorzystaj z tej witryny . Konwertuje dowolne polecenie curl na Python, Node.js, PHP, R lub Go.

Przykład:

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

Staje się tym w Pythonie,

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
źródło
3
Aby upewnić się, że JSON jest poprawnie sformatowany, zaimportuj moduł „json” i użyj json.dumps (payload) na ładunku danych, tj. Data = json.dumps (data) w powyższym przypadku
Richard Bown
23
import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json

może?

jeśli próbujesz wysłać plik

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

ahh dzięki @LukasGraf teraz lepiej rozumiem, co robi jego oryginalny kod

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
źródło
Nie obejmuje to jednak danych z requests.jsonpliku i nie ustawia Content-Type: application/jsonnagłówka - również wyśle GETżądanie, a nie plik POST.
Lukas Graf,
1
curl -d @<file>odczyta pola do wysłania <file>- to nie to samo, co przesłanie pliku.
Lukas Graf,
@LukasGraf dzięki :) ... ja nie używaj pozwijane dużo (czytaj: prawie nigdy)
Jøran Beasley
Jedna mała uwaga, data = requests.get(url).jsonpowinny byćdata = requests.get(url).json()
dpg5000
w 2014 roku była to nieruchomość, teraz jej funkcja :) chociaż dobry telefon
Joran Beasley
19
curl -d @request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere

jego implementacja w Pythonie wygląda jak

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)

sprawdź ten link , pomoże to przekonwertować polecenie cURl na python, php i nodejs

cryptoKTM
źródło
8

Moja odpowiedź to 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

Przepraszam, że nie podałem wymaganych parametrów, bo to poufne.

apoorva_bhat
źródło
Jeśli potrzebujesz użyć niektórych opcji specjalnych z curl, takich jak --resolve, to jest sposób. Dziękuję Ci.
nikoskip
jak mogę uzyskać tylko zwrócony
plik
5

Trochę tła: szukałem dokładnie tego pytania, ponieważ musiałem coś zrobić, aby pobrać zawartość, ale wszystko, co miałem, to stara wersja Pythona z niewystarczającą obsługą SSL. Jeśli korzystasz ze starszego MacBooka, wiesz, o czym mówię. W każdym razie curldziała dobrze z powłoki (podejrzewam, że ma podłączoną nowoczesną obsługę SSL), więc czasami chcesz to zrobić bez użycia requestslub urllib2.

Możesz użyć subprocessmodułu do wykonania curli uzyskania pobranej treści:

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

subprocessModuł Pythona 3 zawiera również .run()szereg przydatnych opcji. Zostawię to komuś, kto faktycznie używa Pythona 3, aby udzielił odpowiedzi.

joemadeus
źródło
-4

Można to osiągnąć dzięki opisanemu poniżej podejściu do kodu pseudo

Importuj żądania importu systemu operacyjnego Data = os.execute (curl URL) R = Data.json ()

user9761315
źródło
os.system zamiast os.execute, aw tym przypadku żądania wydają się niepotrzebne
SeanFromIT