Python'da CURL alternatifi


114

PHP'de kullandığım bir cURL çağrım var:

curl -i -H 'Kabul et: application / xml' -u oturum açma: anahtar " https://app.streamsend.com/emails "

Aynı şeyi Python'da yapmanın bir yolunu bulmalıyım. Python'da cURL'ye bir alternatif var mı? Urllib'i biliyorum ama ben bir Python noob'um ve nasıl kullanılacağı hakkında hiçbir fikrim yok.



2
urllib2, bu tür işler için yaygın olarak kullanılan bir pakettir.
Saurav


3
Yukarıdakiler, requestspython'da basit http yapmak için harika bir kitaplığın bağlantısıdır (PyPi'de easy_install veya pip aracılığıyla kurulabilir). İsim / URL biraz kafa karıştırıcı - ilk başta urllib2bunun daha iyisi için bir istek listesi isteği olduğunu düşündüm , bunun yerine requestskullanımı çok sezgisel ve kullanımı kolay bir pythonic kitaplığı sudo easy_install requestsveya sudo pip install requests.
dr jimbob

Yanıtlar:


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

Bunun yerine urllib2 kullanan cURL aramanız. Tamamen denenmemiş.


4
Bunu aşağıdaki yanıtla karşılaştırmak ve Python'un son dört yılda ne kadar ilerlediğini görmek güzel
Razi Shaban

133

İstekler: İnsanlar için HTTP kullanıcı kılavuzunda açıklanan HTTP İsteklerini kullanabilirsiniz .


2
Talepler en son ve en iyisidir! Sigara içiyor ve sakar urllib2'yi yakıyor, keşke isteklerin python gelen 3.x sürümleri için standart HTTP İstemcisi olmasını diliyorum
Phyo Arkar Lwin

1
İstekleri kullanmaya geçtiğimde artık urllib2'yi doğrudan kullanmaya hiç bakmadım. Yerleşik JSON kod çözme de kullanışlıdır. Uygun içerik türü ayarlanmışsa, json ile gövdeyi manuel olarak yüklemeye gerek yoktur.
Thomas Farvour

İstekler çok basit. Birkaç dakika içinde özel bir kimlik doğrulama şeması bile oluşturabildim. urllib2 çok sinir bozucudur.
Doug

35

Burada, GitHub API'sine karşı temel bir kimlik doğrulaması yapan urllib2 kullanan basit bir örnek verilmiştir.

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

Ayrıca, bunu bir betiğe sararsanız ve onu bir terminalden çalıştırırsanız, hoş yazdırmayı etkinleştirmek için yanıt dizesini 'mjson.tool'a yönlendirebilirsiniz.

>> basicAuth.py | python -mjson.tool

Unutulmaması gereken son bir nokta, urllib2 yalnızca GET & POST isteklerini destekler.
DELETE, PUT, vb. Gibi diğer HTTP fiillerini kullanmanız gerekiyorsa, muhtemelen PYCURL'ye bir göz atmak isteyeceksiniz.


Bu neden reddedildi? Belki de PycURL yerine PYCURL yazdığınız içindir: D
Rao

20

Curl'yi böyle çağırmak için bir komut kullanıyorsanız, aynı şeyi Python'da da yapabilirsiniz subprocess. Misal:

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

Ya da PHP'nin sahip olduğu gibi daha yapılandırılmış bir api olarak sahip olmak istiyorsanız PycURL'yi deneyebilirsiniz .


Hayır. CURL çağrısı bir programın parçasıdır. Yukarıdaki curl çağrısında yapılanla aynı şeyi yapan kodu gönderebilirseniz, bu harika olurdu.
Gaurav Sharma

Sorunuza göre alt işlem kullanarak neyi kastettiğime dair bir örnek ekledim ama sanırım daha çok PycURL gibi bir şey arıyorsunuz.
unholysampler

Bunun daha eski olduğunu biliyorum, ancak bence çoğu cURL kullanımı için PycURL oldukça düşük seviyede. CURL'nin PHP uygulaması bile oldukça düşük seviyededir.
Thomas Farvour

Cmd'den "python" u çağırdıktan ve dolayısıyla python env içinde olduktan sonra "isim hatası, isim alt işlemi tanımlanmadı" mesajı alıyorum.
Timo

@Timo yaptın mı import subprocess? Python repl ortamı tıpkı bir python dosyası gibidir, diğer modülleri içe aktarmanız gerekir.
unholysampler

13
import requests

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

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

Bu onu elde edebildiğim en basit şey.


Bu en basit cevap! urllib2aşırı karmaşık.
not2qubit

7

Bir örnek, bazı şeker sözdizimi ile bu şeyler için urllib nasıl kullanılır. İstekleri ve diğer kitaplıkları biliyorum, ancak urllib python için standart kitaplıktır ve herhangi bir şeyin ayrı olarak kurulmasını gerektirmez.

Python 2/3 uyumlu.

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"})

İşlev tam değildir ve muhtemelen ideal değildir, ancak kullanılacak temel bir temsil ve konsept gösterir. Ek şeyler zevke göre eklenebilir veya değiştirilebilir.

12/08 güncelleme

İşte canlı güncellenmiş kaynağa bir GitHub bağlantısı. Şu anda destekleniyor:

  • yetki

  • CRUD uyumlu

  • otomatik karakter kümesi algılama

  • otomatik kodlama (sıkıştırma) algılama


4

Yukarıdakilerin hepsini aradığınız komut satırından çalıştırıyorsa, HTTPie'yi öneririm . Harika bir cURL alternatifidir ve kullanımı (ve özelleştirmesi) süper kolay ve kullanışlıdır .

İşte GitHub'ın (kısa ve öz) açıklaması;

HTTPie (aych-tee-tee-pie olarak okunur) bir komut satırı HTTP istemcisidir. Amacı, web hizmetleriyle CLI etkileşimini olabildiğince insan dostu hale getirmektir.

Basit ve doğal bir sözdizimi kullanarak rastgele HTTP istekleri göndermeye izin veren basit bir http komutu sağlar ve renklendirilmiş çıktıyı görüntüler. HTTPie, test etmek, hata ayıklamak ve genellikle HTTP sunucularıyla etkileşim kurmak için kullanılabilir.


Kimlik doğrulama ile ilgili dokümantasyon , problemlerinizi çözmeniz için size yeterli işaretçi sağlamalıdır. Elbette, yukarıdaki yanıtların tümü de doğrudur ve aynı görevi yerine getirmenin farklı yollarını sağlar.


Sırf Stack Overflow'dan uzaklaşmanıza gerek YOKTUR, işte kısaca sunduğu şey.

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


belki hiç anlamadım ama bu bir Python modülü mü? Sanırım bu bir kabuk / CLI aracı ve
Alex

@Alex - Bir Python modülüdür. Github'daki README ( github.com/jkbrzt/httpie ) ihtiyacınız olan her şeyi içerir.
stuxnetting
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.