CURL альтернатива в Python


114

У мене є виклик CURL, який я використовую в PHP:

curl -i -H 'Прийняти: application / xml' -u login: key " https://app.streamsend.com/emails "

Мені потрібен спосіб зробити те ж саме в Python. Чи є альтернатива cURL в Python. Я знаю про urllib, але я нобіт Python і не маю уявлення, як ним користуватися.


2
Ви можете спробувати pycurl
ghostdog74

2
urllib2 - це широко використовуваний пакет для подібних робіт.
Саурав


3
Наведене вище - посилання для чудової бібліотеки, щоб зробити простий http requestsу python (доступний для встановлення через easy_install або pip в PyPi). Ім'я / URL трохи заплутано - спочатку я майже думав, що це запит у побажання на краще urllib2, натомість requestsдуже інтуїтивно зрозуміла пітонічна бібліотека sudo easy_install requestsчи проста у використанні sudo pip install requests.
dr jimbob

Python Requests проти PyCurl Performance Ви пристойні у своїй вимозі
Santhosh,

Відповіді:


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

Ваш виклик CURL використовує натомість urllib2. Повністю неперевірений.


4
Приємно порівняти це з відповіддю внизу та побачити, як далеко прогресував Python за останні чотири роки
Разі Шабан

133

Ви можете використовувати Запити HTTP, описані в посібнику користувача Запити: HTTP для людей .


2
Запити найновіші та найбільші! Він курить і спалює незграбний urllib2, я хочу, щоб запити стали стандартним HTTP-клієнтом для вхідних версій python 3.x
Phyo

1
Коли я перейшов на використання запитів, я більше не звертався до використання urllib2 безпосередньо. Також зручно вбудоване декодування JSON. Не потрібно вручну завантажувати тіло json, якщо встановлено відповідний тип вмісту.
Томас Фарвур

Запити такі прості. Мені навіть вдалося створити власну схему аутентифікації за кілька хвилин. urllib2 - це супер дратує.
Дуг

35

Ось простий приклад використання urllib2, який робить основну автентифікацію проти 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()

Крім того, якщо ви загортаєте це в сценарій і запускаєте його з терміналу, ви можете передавати рядок відповідей на 'mjson.tool', щоб забезпечити гарну друк.

>> basicAuth.py | python -mjson.tool

Останнє, що потрібно зазначити, urllib2 підтримує лише запити GET & POST.
Якщо вам потрібно використовувати інші дієслова HTTP, такі як DELETE, PUT тощо, ви, ймовірно, захочете поглянути на PYCURL


Чому це було проголосовано? Можливо тому, що ви написали PYCURL замість PycURL: D
Bhargav Rao

20

Якщо ви використовуєте команду для просто виклику curl так, ви можете зробити те саме, що і в Python subprocess. Приклад:

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

Або ви можете спробувати PycURL, якщо ви хочете мати його як більш структурований api, як у PHP.


Ні. Виклик CURL є частиною програми. Якщо ви зможете опублікувати код, який робить саме те, що робиться у виклику curl вище, це було б чудово.
Gaurav Sharma

Додав приклад того, що я мав на увазі, використовуючи підпроцес на основі вашого запитання, але я здогадуюсь, що ви шукаєте щось подібне до PycURL.
unholysampler

Я знаю, що це старше, але на мою думку, PycURL є досить низьким для більшості випадків використання CURL. Навіть PHP-реалізація CURL є досить низьким рівнем.
Томас Фарвур

Я отримую "помилка імені, підпроцес імені не визначено" після виклику "python" з cmd і тому знаходяться в оточенні python.
Тимо

@Timo Ти що import subprocess? Середовище відтворення python подібно до файлу python, вам потрібно імпортувати інші модулі.
unholysampler

13
import requests

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

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

Це найпростіше, що мені вдалося отримати.


Це найпростіша відповідь! urllib2надмірно складний.
not2qubit

7

Деякі приклади, як використовувати urllib для цих речей із синтаксисом цукру. Я знаю про запити та інші бібліотеки, але urllib є стандартною lib для python і не вимагає нічого встановлювати окремо.

Сумісний 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"})

Функція не є повною і, можливо, не є ідеальною, але показує базове уявлення та концепцію, яку слід використовувати. Додаткові речі можна додати або змінити за смаком.

12/08 оновлення

Ось посилання GitHub на оновлене джерело. На даний момент підтримує:

  • дозволу

  • Сумісна з CRUD

  • автоматичне виявлення шаблонів

  • автоматичне виявлення (стиснення) кодування


4

Якщо все вищезазначене працює з командного рядка, який ви шукаєте, я рекомендую HTTPie . Це фантастична альтернатива CURL і дуже проста та зручна у використанні (та налаштування).

Ось його (стислий та точний) опис від GitHub;

HTTPie (вимовляється aych-tee-tee-pie) - клієнтський рядок HTTP-клієнта. Його мета - зробити взаємодію CLI з веб-сервісами максимально зручною для людини.

Він забезпечує просту команду http, яка дозволяє надсилати довільні запити HTTP, використовуючи простий і природний синтаксис, і відображає кольоровий вихід. HTTPie можна використовувати для тестування, налагодження та взагалі взаємодії з HTTP-серверами.


Документація навколо автентифікації повинна дати вам достатньо покажчиків для вирішення ваших проблем. Звичайно, всі відповіді, наведені вище, є точними і дають різні способи виконання одного і того ж завдання.


Просто так НЕ потрібно віддалятися від Stack Overflow, ось що він пропонує в двох словах.

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


можливо, я його взагалі не отримав, але це модуль Python? Я думаю, це інструмент оболонки / CLI, і мене знеструмлено: '(це здавалося, що це так просто у використанні
Алекс

@Alex - це модуль Python. README в Github ( github.com/jkbrzt/httpie ) містить все необхідне.
приголомшливий
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.