2010-01-02 46 views
20

Tôi muốn chuyển đổi lệnh curl này thành lệnh mà tôi có thể sử dụng bằng Python cho tập lệnh hiện có.Chuyển đổi yêu cầu POST curl sang Python chỉ bằng cách sử dụng thư viện chuẩn

curl -u 7898678:X -H 'Content-Type: application/json' \ 
-d '{"message":{"body":"TEXT"}}' http://sample.com/36576/speak.json 

TEXT là những gì tôi muốn thay thế bằng một thông điệp được tạo ra bởi phần còn lại của kịch bản (nào đã được làm việc hợp lý, mặc dù tôi không nghĩ rằng đó là sau thực hành tốt nhất hoặc đặc thù đáng tin cậy -.. Cần để tìm hiểu cách học đúng cách để lập trình (tức là không sử dụng google để lắp ráp các công cụ))

Tôi muốn làm việc này với thư viện chuẩn nếu có thể.

+1

Tới đây - http://stackoverflow.com/questions/4348061/how-to-use-python-urllib2-to-send-json- data-for-login/7469725 # 7469725 – treecoder

Trả lời

23

Tôi muốn này để làm việc với các thư viện chuẩn nếu có thể.

Các thư viện chuẩn cung cấp urllibhttplib để làm việc với URL:

>>> import httplib, urllib 
>>> params = urllib.urlencode({'apple': 1, 'banana': 2, 'coconut': 'yummy'}) 
>>> headers = {"Content-type": "application/x-www-form-urlencoded", 
...   "Accept": "text/plain"} 
>>> conn = httplib.HTTPConnection("example.com:80") 
>>> conn.request("POST", "/some/path/to/site", params, headers) 
>>> response = conn.getresponse() 
>>> print response.status, response.reason 
200 OK 

Nếu bạn muốn thực hiện curl chính nó, tuy nhiên, bạn có thể chỉ cần gọi os.system():

import os 
TEXT = ... 
cmd = """curl -u 7898678:X -H 'Content-Type: application/json'""" \ 
    """-d '{"message":{"body":"%{t}"}}' http://sample.com/36576/speak.json""" % \ 
    {'t': TEXT} 

Nếu bạn sẵn sàng thư giãn giới hạn chỉ dành cho thư viện chuẩn, bạn có thể sử dụng PycURL. Cẩn thận rằng nó không phải là rất Pythonic (nó khá nhiều chỉ là một veneer mỏng trên libcurl), và tôi không chắc chắn như thế nào tương thích với Python 3.

+0

Sử dụng httplib có nghĩa là bỏ qua một số tính năng từ urllib và urllib2, như hỗ trợ cho proxy. –

+1

@dalke »Đúng vậy; đây chỉ là một ví dụ đơn giản để thực hiện yêu cầu 'GET' hoặc' POST', đó là tôi nghĩ OP là gì sau đó. –

+2

'tis true.Tôi chỉ thấy rằng bằng cách sử dụng httplib và làm URL munging không phải là thường có giá trị nỗ lực cho rằng urllib2 cung cấp cho bạn tất cả những điều đó và nhiều hơn nữa. –

12

Trong khi có nhiều cách để xử lý authentication in urllib2, nếu bạn làm cơ bản ủy quyền (có nghĩa là gửi một cách hiệu quả tên người dùng và mật khẩu trong văn bản rõ ràng) sau đó bạn có thể làm tất cả những gì bạn muốn với một urllib2.Request và urllib2.urlopen:

import urllib2 

def basic_authorization(user, password): 
    s = user + ":" + password 
    return "Basic " + s.encode("base64").rstrip() 

req = urllib2.Request("http://localhost:8000/36576/speak.json", 
         headers = { 
     "Authorization": basic_authorization("7898678", "X"), 
     "Content-Type": "application/json", 

     # Some extra headers for fun 
     "Accept": "*/*", # curl does this 
     "User-Agent": "my-python-app/1", # otherwise it uses "Python-urllib/..." 
     }, 
         data = '{"message":{"body":"TEXT"}}') 

f = urllib2.urlopen(req) 

tôi thử nghiệm này với netcat vì vậy tôi có thể thấy rằng dữ liệu được gửi là, ngoại trừ thứ tự sắp xếp, giống hệt nhau trong cả hai trường hợp. Dưới đây là người đầu tiên đã được thực hiện với curl và lần thứ hai với urllib2

% nc -l 8000 
POST /36576/speak.json HTTP/1.1 
Authorization: Basic Nzg5ODY3ODpY 
User-Agent: curl/7.19.4 (universal-apple-darwin10.0) libcurl/7.19.4 OpenSSL/0.9.8k zlib/1.2.3 
Host: localhost:8000 
Accept: */* 
Content-Type: application/json 
Content-Length: 27 

{"message":{"body":"TEXT"}} ^C 

% nc -l 8000 
POST /36576/speak.json HTTP/1.1 
Accept-Encoding: identity 
Content-Length: 27 
Connection: close 
Accept: */* 
User-Agent: my-python-app/1 
Host: localhost:8000 
Content-Type: application/json 
Authorization: Nzg5ODY3ODpY 

{"message":{"body":"TEXT"}}^C 

(này là hơi tinh chỉnh từ đầu ra. Trường hợp thử nghiệm của tôi không sử dụng đường dẫn url mà bạn đã dùng.)

Không có cần sử dụng httplib cơ bản, không hỗ trợ những thứ mà urllib2 cung cấp cho bạn như hỗ trợ proxy. Mặt khác, tôi thấy urllib2 phức tạp bên ngoài loại yêu cầu đơn giản này và nếu bạn muốn hỗ trợ tốt hơn cho các tiêu đề nào được gửi và thứ tự chúng được gửi thì sử dụng httplib.

+0

cảm ơn bạn đã nhập đoạn mã net – nkint

2

Cảm ơn tất cả các

làm việc này

import urllib2 

def speak(status): 

    def basic_authorization(user, password): 
     s = user + ":" + password 
     return "Basic " + s.encode("base64").rstrip() 

    req = urllib2.Request("http://example.com/60/speak.json", 
        headers = { 
     "Authorization": basic_authorization("2345670", "X"), 
    "Content-Type": "application/json", 


     "Accept": "*/*", 
     "User-Agent": "my-python-app/1", 
     }, 
         data = '{"message":{"body":'+ status +'}}') 

    f = urllib2.urlopen(req) 


speak('Yay') 
Các vấn đề liên quan