Alternatywa CURL w Pythonie


114

Mam wywołanie cURL, którego używam w PHP:

curl -i -H „Akceptuj: aplikacja / xml” -u login: klucz „ https://app.streamsend.com/emails

Potrzebuję sposobu, aby zrobić to samo w Pythonie. Czy istnieje alternatywa dla cURL w Pythonie? Znam urllib, ale jestem noobem Pythona i nie mam pojęcia, jak go używać.


2
Możesz spróbować pycurl
ghostdog74

2
urllib2 jest pakietem powszechnie używanym do tego rodzaju pracy.
Saurav


3
Powyższy link to świetna biblioteka do prostego http requestsw pythonie (dostępna do zainstalowania przez easy_install lub pip w PyPi). Nazwa / adres URL jest nieco myląca - na początku prawie myślałem, że to prośba o listę życzeń, aby uzyskać lepszą urllib2, zamiast tego requestsbardzo intuicyjną i łatwą w użyciu bibliotekę Pythona sudo easy_install requestslub sudo pip install requests.
dr jimbob

Python vs pycurl Wnioski Wyniki You przyzwoitych od Państwa wymagań
Santhosh

Odpowiedzi:


68
import urllib2

manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
manager.add_password(None, 'https://app.streamsend.com/emails', 'login', 'key')
handler = urllib2.HTTPBasicAuthHandler(manager)

director = urllib2.OpenerDirector()
director.add_handler(handler)

req = urllib2.Request('https://app.streamsend.com/emails', headers = {'Accept' : 'application/xml'})

result = director.open(req)
# result.read() will contain the data
# result.info() will contain the HTTP headers

# To get say the content-length header
length = result.info()['Content-Length']

Zamiast tego wywołanie cURL przy użyciu urllib2. Całkowicie niesprawdzone.


4
Miło jest porównać to z odpowiedzią poniżej i zobaczyć, jak daleko posunął się Python w ciągu ostatnich czterech lat
Razi Shaban

133

Możesz używać żądań HTTP opisanych w podręczniku użytkownika Żądania: HTTP dla ludzi .


2
Żądania są najnowsze i najlepsze! Dymi i pali niezdarne urllib2, chciałbym, żeby żądania
stały

1
Kiedy przeszedłem na używanie żądań, nigdy więcej nie wracałem do bezpośredniego używania urllib2. Wbudowane dekodowanie JSON jest również przydatne. Nie ma potrzeby ręcznego ładowania treści przy użyciu json, jeśli jest ustawiony odpowiedni typ zawartości.
Thomas Farvour

Żądania są takie proste. Udało mi się nawet stworzyć niestandardowy schemat uwierzytelniania w ciągu kilku minut. urllib2 jest bardzo irytujące.
Doug

35

Oto prosty przykład użycia urllib2, który przeprowadza podstawowe uwierzytelnianie względem interfejsu API GitHub.

import urllib2

u='username'
p='userpass'
url='https://api.github.com/users/username'

# simple wrapper function to encode the username & pass
def encodeUserData(user, password):
    return "Basic " + (user + ":" + password).encode("base64").rstrip()

# create the request object and set some headers
req = urllib2.Request(url)
req.add_header('Accept', 'application/json')
req.add_header("Content-type", "application/x-www-form-urlencoded")
req.add_header('Authorization', encodeUserData(u, p))
# make the request and print the results
res = urllib2.urlopen(req)
print res.read()

Ponadto, jeśli zawiniesz to w skrypt i uruchomisz go z terminala, możesz przesłać łańcuch odpowiedzi do 'mjson.tool', aby umożliwić ładne drukowanie.

>> basicAuth.py | python -mjson.tool

Ostatnia rzecz, na którą należy zwrócić uwagę, urllib2 obsługuje tylko żądania GET i POST.
Jeśli potrzebujesz innych czasowników HTTP, takich jak DELETE, PUT itp., Prawdopodobnie zechcesz rzucić okiem na PYCURL


Dlaczego głosowanie odrzucono? Być może dlatego, że zamiast PycURL napisałeś PYCURL: D
Bhargav Rao

20

Jeśli używasz polecenia do wywołania curl w ten sposób, możesz zrobić to samo w Pythonie za pomocą subprocess. Przykład:

subprocess.call(['curl', '-i', '-H', '"Accept: application/xml"', '-u', 'login:key', '"https://app.streamsend.com/emails"'])

Lub możesz wypróbować PycURL, jeśli chcesz, aby był on bardziej ustrukturyzowanym interfejsem API, takim jak PHP.


Nie. Wywołanie cURL jest częścią programu. Byłoby wspaniale, gdybyś mógł opublikować kod, który robi dokładnie to samo, co w wywołaniu curl powyżej.
Gaurav Sharma

Dodano przykład, co miałem na myśli, używając podprocesu na podstawie twojego pytania, ale domyślam się, że szukasz czegoś bardziej jak PycURL.
unholysampler

Wiem, że to jest starsze, ale moim zdaniem PycURL jest dość niski dla większości zastosowań cURL. Nawet implementacja cURL w PHP jest na dość niskim poziomie.
Thomas Farvour

Otrzymuję komunikat „błąd nazwy, nie zdefiniowano podprocesu nazwy” po wywołaniu „python” z cmd, a zatem będąc w pythonie env.
Timo,

@Timo Czy ty import subprocess? Środowisko replik Pythona jest jak plik pythona, musisz zaimportować inne moduły.
unholysampler

13
import requests

url = 'https://example.tld/'
auth = ('username', 'password')

r = requests.get(url, auth=auth)
print r.content

To najprostszy, jaki udało mi się zdobyć.


To najprostsza odpowiedź! urllib2jest zbyt skomplikowane.
not2qubit

7

Oto przykład, jak używać urllib do tych rzeczy, z pewną składnią cukru. Wiem o żądaniach i innych bibliotekach, ale urllib jest standardową biblioteką dla Pythona i nie wymaga oddzielnej instalacji.

Kompatybilny z Python 2/3.

import sys
if sys.version_info.major == 3:
  from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib.parse import urlencode
else:
  from urllib2 import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, Request, build_opener
  from urllib import urlencode


def curl(url, params=None, auth=None, req_type="GET", data=None, headers=None):
  post_req = ["POST", "PUT"]
  get_req = ["GET", "DELETE"]

  if params is not None:
    url += "?" + urlencode(params)

  if req_type not in post_req + get_req:
    raise IOError("Wrong request type \"%s\" passed" % req_type)

  _headers = {}
  handler_chain = []

  if auth is not None:
    manager = HTTPPasswordMgrWithDefaultRealm()
    manager.add_password(None, url, auth["user"], auth["pass"])
    handler_chain.append(HTTPBasicAuthHandler(manager))

  if req_type in post_req and data is not None:
    _headers["Content-Length"] = len(data)

  if headers is not None:
    _headers.update(headers)

  director = build_opener(*handler_chain)

  if req_type in post_req:
    if sys.version_info.major == 3:
      _data = bytes(data, encoding='utf8')
    else:
      _data = bytes(data)

    req = Request(url, headers=_headers, data=_data)
  else:
    req = Request(url, headers=_headers)

  req.get_method = lambda: req_type
  result = director.open(req)

  return {
    "httpcode": result.code,
    "headers": result.info(),
    "content": result.read()
  }


"""
Usage example:
"""

Post data:
  curl("http://127.0.0.1/", req_type="POST", data='cascac')

Pass arguments (http://127.0.0.1/?q=show):
  curl("http://127.0.0.1/", params={'q': 'show'}, req_type="POST", data='cascac')

HTTP Authorization:
  curl("http://127.0.0.1/secure_data.txt", auth={"user": "username", "pass": "password"})

Funkcja nie jest kompletna i prawdopodobnie nie jest idealna, ale przedstawia podstawową reprezentację i koncepcję do wykorzystania. Dodatkowe rzeczy można dodać lub zmienić według gustu.

Aktualizacja 12/08

Oto łącze GitHub do aktualizowanego na żywo źródła. Obecnie wspiera:

  • upoważnienie

  • Kompatybilny z CRUD

  • automatyczne wykrywanie zestawu znaków

  • automatyczne wykrywanie kodowania (kompresji)


4

Jeśli wszystkie powyższe funkcje są uruchamiane z wiersza poleceń, którego szukasz, polecam HTTPie . Jest to fantastyczna alternatywa dla cURL, super łatwa i wygodna w użyciu (i dostosowywaniu).

Oto jego (zwięzły i dokładny) opis z GitHub;

HTTPie (wymawiane aych-tee-tee-pie) to klient HTTP wiersza poleceń. Jego celem jest uczynienie interakcji CLI z usługami sieciowymi tak przyjaznymi dla człowieka, jak to tylko możliwe.

Udostępnia proste polecenie http, które umożliwia wysyłanie dowolnych żądań HTTP przy użyciu prostej i naturalnej składni oraz wyświetla kolorowe dane wyjściowe. HTTPie może być używany do testowania, debugowania i ogólnie do interakcji z serwerami HTTP.


Dokumentacja dotycząca uwierzytelniania powinna zawierać wystarczającą liczbę wskazówek, aby rozwiązać problem (y). Oczywiście wszystkie powyższe odpowiedzi są również dokładne i zapewniają różne sposoby wykonania tego samego zadania.


Aby NIE musieć odchodzić od Stack Overflow, oto, co oferuje w skrócie.

Basic auth:

$ http -a username:password example.org
Digest auth:

$ http --auth-type=digest -a username:password example.org
With password prompt:

$ http -a username example.org


może w ogóle tego nie rozumiem, ale czy jest to moduł Pythona? Myślę, że to narzędzie powłoki / CLI i jestem rozczarowany: `` (wydawało się, że jest tak łatwy w użyciu
Alex

@Alex - Jest to moduł Pythona. README na Github ( github.com/jkbrzt/httpie ) zawiera wszystko, czego potrzebujesz.
stuxnetting
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.