CURL thay thế bằng Python


114

Tôi có một lệnh gọi cURL mà tôi sử dụng trong PHP:

curl -i -H 'Chấp nhận: application / xml' -u đăng nhập: key " https://app.streamsend.com/emails "

Tôi cần một cách để làm điều tương tự bằng Python. Có một giải pháp thay thế cho cURL trong Python không. Tôi biết về urllib nhưng tôi là một người dùng Python và không biết cách sử dụng nó.


2
Bạn có thể thử pycurl
ghostdog. 74

2
urllib2 là một gói được sử dụng rộng rãi cho loại công việc này.
Saurav


3
Trên đây là liên kết cho một thư viện tuyệt vời để thực hiện http requeststrong python đơn giản (có sẵn để cài đặt thông qua easy_install hoặc pip trong PyPi). Tên / URL hơi khó hiểu - lúc đầu, tôi gần như nghĩ rằng đây là một yêu cầu trong danh sách mong muốn để tốt hơn urllib2, thay vào đó requestslà một thư viện pythonic rất trực quan dễ sử dụng sudo easy_install requestshoặc sudo pip install requests.
dr jimbob 29/02/12

Yêu cầu Python so với Hiệu suất PyCurl Bạn thực hiện tốt yêu cầu của mình
Santhosh

Câu trả lời:


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

Cuộc gọi cURL của bạn bằng urllib2 thay thế. Hoàn toàn chưa được kiểm tra.


4
Thật tuyệt khi so sánh điều này với câu trả lời ngay bên dưới và xem Python đã tiến bộ như thế nào trong bốn năm qua
Razi Shaban

133

Bạn có thể sử dụng Yêu cầu HTTP được mô tả trong Hướng dẫn sử dụng Yêu cầu: HTTP cho Con người.


2
Yêu cầu là mới nhất và lớn nhất! Nó hút thuốc lá và đốt cháy urllib2 vụng về, tôi muốn yêu cầu trở thành tiêu chuẩn khách hàng HTTP cho python phiên bản 3.x đến
Phyo Arkar Lwin

1
Khi tôi chuyển sang sử dụng các yêu cầu, tôi không bao giờ quay lại sử dụng trực tiếp urllib2 nữa. Giải mã JSON tích hợp cũng rất tiện dụng. Không cần phải tải nội dung bằng json theo cách thủ công nếu loại nội dung thích hợp được đặt.
Thomas Farvour

Yêu cầu rất đơn giản. Tôi thậm chí đã có thể tạo một sơ đồ xác thực tùy chỉnh trong vài phút. urllib2 là siêu khó chịu.
Doug

35

Đây là một ví dụ đơn giản sử dụng urllib2 thực hiện xác thực cơ bản đối với API của 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()

Hơn nữa, nếu bạn bọc nó trong một tập lệnh và chạy nó từ một thiết bị đầu cuối, bạn có thể chuyển chuỗi phản hồi đến 'mjson.tool' để cho phép in đẹp.

>> basicAuth.py | python -mjson.tool

Một điều cuối cùng cần lưu ý, urllib2 chỉ hỗ trợ các yêu cầu GET & POST.
Nếu bạn cần sử dụng các động từ HTTP khác như DELETE, PUT, v.v. thì có thể bạn sẽ muốn xem qua PYCURL


Tại sao điều này bị bỏ phiếu? Có lẽ vì bạn đã viết PYCURL thay vì PycURL: D
Bhargav Rao

20

Nếu bạn đang sử dụng một lệnh để chỉ gọi curl như vậy, bạn có thể làm điều tương tự trong Python với subprocess. Thí dụ:

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

Hoặc bạn có thể thử PycURL nếu bạn muốn có nó dưới dạng một api có cấu trúc hơn như những gì PHP có.


Không. Cuộc gọi cURL là một phần của chương trình. Nếu bạn có thể đăng mã thực hiện điều tương tự đang được thực hiện trong lệnh gọi curl ở trên, điều đó sẽ thật tuyệt.
Gaurav Sharma

Đã thêm một ví dụ về ý của tôi khi sử dụng quy trình con dựa trên câu hỏi của bạn, nhưng tôi đoán bạn đang tìm kiếm thứ gì đó giống PycURL hơn.
unholysampler

Tôi biết điều này cũ hơn, nhưng PycURL là mức khá thấp đối với hầu hết các cách sử dụng cURL theo ý kiến ​​của tôi. Ngay cả việc triển khai cURL trong PHP cũng khá thấp.
Thomas Farvour

Tôi nhận được "lỗi tên, quy trình con tên không được xác định" sau khi gọi "python" từ cmd và do đó đang ở trong python env.
Timo

@Timo Bạn đã biết import subprocesschưa? Môi trường python repl cũng giống như một tệp python, bạn phải nhập các mô-đun khác.
unholysampler

13
import requests

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

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

Đây là cách đơn giản nhất mà tôi có thể làm được.


Đây là câu trả lời đơn giản nhất! urllib2là quá phức tạp.
not2qubit 22/09/18

7

Một số ví dụ, cách sử dụng urllib cho những thứ đó, với một số cú pháp đường. Tôi biết về các yêu cầu và các thư viện khác, nhưng urllib là lib tiêu chuẩn cho python và không yêu cầu cài đặt riêng bất kỳ thứ gì.

Tương thích với 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"})

Chức năng không hoàn chỉnh và có thể không lý tưởng, nhưng cho thấy một đại diện và khái niệm cơ bản để sử dụng. Những thứ bổ sung có thể được thêm vào hoặc thay đổi theo sở thích.

12/08 cập nhật

Đây là một liên kết GitHub đến nguồn cập nhật trực tiếp. Hiện đang hỗ trợ:

  • ủy quyền

  • CRUD tương thích

  • phát hiện bộ ký tự tự động

  • phát hiện mã hóa (nén) tự động


4

Nếu nó đang chạy tất cả những điều trên từ dòng lệnh mà bạn đang tìm kiếm, thì tôi khuyên bạn nên sử dụng HTTPie . Nó là một giải pháp thay thế cURL tuyệt vời và siêu dễ dàngthuận tiện để sử dụng (và tùy chỉnh).

Đây là mô tả (ngắn gọn và chính xác) của nó từ GitHub;

HTTPie (phát âm là aych-tee-tee-pie) là một ứng dụng khách HTTP dòng lệnh. Mục tiêu của nó là làm cho tương tác của CLI với các dịch vụ web thân thiện với con người nhất có thể.

Nó cung cấp một lệnh http đơn giản cho phép gửi các yêu cầu HTTP tùy ý bằng cú pháp đơn giản và tự nhiên, đồng thời hiển thị đầu ra được tô màu. HTTPie có thể được sử dụng để kiểm tra, gỡ lỗi và tương tác chung với các máy chủ HTTP.


Tài liệu về xác thực sẽ cung cấp cho bạn đủ gợi ý để giải quyết (các) vấn đề của bạn. Tất nhiên, tất cả các câu trả lời ở trên cũng chính xác và cung cấp các cách khác nhau để hoàn thành cùng một nhiệm vụ.


Để bạn KHÔNG phải di chuyển khỏi Stack Overflow, tóm lại đây là những gì nó cung cấp.

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


có lẽ tôi đã không hiểu nó, nhưng nó có phải là một mô-đun Python không? Tôi đoán nó là một công cụ shell / CLI, và tôi thất vọng: '(nó có vẻ rất dễ sử dụng
Alex.

@Alex - Nó là một mô-đun Python. README trên Github ( github.com/jkbrzt/httpie ) chứa mọi thứ bạn cần.
stuxnetting
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.