杰瑞科技汇

Python urllib2如何实现POST请求?

Of course! The request is for urllib2, which is a module from Python 2.

Python urllib2如何实现POST请求?-图1
(图片来源网络,侵删)

It's very important to know that urllib2 does not exist in Python 3. In Python 3, it was split into urllib.request and urllib.error. Since you asked for urllib2, I will provide the Python 2 solution first, followed by the modern Python 3 equivalent.


Python 2: Using urllib2 and urllib

In Python 2, to perform a POST request, you needed to use urllib2 and urllib together. urllib was used to encode the dictionary of data into the format application/x-www-form-urlencoded, which is required for form data.

Here is a complete, commented example.

Python 2 Code

import urllib
import urllib2
# The URL of the API endpoint you want to send the POST request to.
# Using a public test API for demonstration: https://httpbin.org/post
# This API will echo back the data it receives.
url = 'https://httpbin.org/post'
# The data you want to send as a dictionary.
# The keys and values will be URL-encoded automatically.
data = {
    'username': 'testuser',
    'password': 'secretpassword',
    'message': 'Hello from Python 2!'
}
# urllib.urlencode() converts the dictionary into a query string:
# "username=testuser&password=secretpassword=message=Hello+from+Python+2%21"
encoded_data = urllib.urlencode(data)
# Some servers might require the data to be passed as bytes.
# In Python 2, a string is often fine, but it's good practice to be explicit.
# We'll encode it to ASCII, which is standard for this type of data.
data_to_send = encoded_data.encode('ascii')
# Create a request object.
# The second argument is the encoded data.
# The third argument, 'Content-Type', tells the server what kind of data we're sending.
# For form data, 'application/x-www-form-urlencoded' is standard.
request = urllib2.Request(url, data=data_to_send, headers={
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Python-urllib2-Post-Example'
})
try:
    # Send the request and get the response.
    # urlopen returns a file-like object that you can read from.
    response = urllib2.urlopen(request)
    # Read the response body.
    # response.read() returns a string.
    response_body = response.read()
    # The response from httpbin.org is in JSON format.
    # Let's print it nicely.
    print "--- Response Status Code ---"
    print response.getcode() # e.g., 200 for OK
    print "\n--- Response Headers ---"
    print response.headers
    print "\n--- Response Body (JSON) ---"
    print response_body
except urllib2.HTTPError as e:
    # Handle HTTP errors (e.g., 404 Not Found, 500 Server Error)
    print "Error code: %s" % e.code
    print e.read() # Read the error body
except urllib2.URLError as e:
    # Handle URL errors (e.g., network connection failed)
    print "Reason: %s" % e.reason

How it Works:

  1. import urllib, urllib2: Import both necessary modules.
  2. data dictionary: Define your key-value pairs.
  3. urllib.urlencode(data): This is the crucial step. It takes the dictionary and turns it into a properly formatted string for a POST request.
  4. urllib2.Request(url, data=..., headers=...): Create a request object. By passing the data argument, you are telling urllib2 to make a POST request instead of a GET. The headers are optional but good practice for specifying content type and user agent.
  5. urllib2.urlopen(request): Execute the request and open the network connection.
  6. response.read(): Read the data sent back by the server.
  7. try...except: It's vital to handle potential network or HTTP errors gracefully.

Python 3: The Modern Way (urllib.request)

In Python 3, urllib2 was split. The functionality for making requests is in urllib.request. The process is slightly cleaner.

Python urllib2如何实现POST请求?-图2
(图片来源网络,侵删)

Python 3 Code

import urllib.parse
import urllib.request
import json # For pretty printing the JSON response
# The URL of the API endpoint
url = 'https://httpbin.org/post'
# The data you want to send as a dictionary
data = {
    'username': 'testuser',
    'password': 'secretpassword',
    'message': 'Hello from Python 3!'
}
# urllib.parse.urlencode() replaces urllib.urlencode()
# It also handles encoding to bytes automatically if you pass it to the request.
encoded_data = urllib.parse.urlencode(data).encode('utf-8')
# Create a request object.
# The headers are passed as a dictionary directly.
request = urllib.request.Request(url, data=encoded_data, headers={
    'Content-Type': 'application/x-www-form-urlencoded',
    'User-Agent': 'Python-urllib3-Post-Example'
})
try:
    # Send the request and get the response.
    # urlopen returns a bytes object in Python 3.
    with urllib.request.urlopen(request) as response:
        # response.read() returns bytes, so we decode it to a string.
        response_body = response.read().decode('utf-8')
    # The response from httpbin.org is in JSON format.
    # Let's print it nicely using the json module.
    response_json = json.loads(response_body)
    print("--- Response Status Code ---")
    print(response.getcode()) # e.g., 200 for OK
    print("\n--- Response Headers ---")
    print(response.headers)
    print("\n--- Response Body (Pretty JSON) ---")
    # Use json.dumps to format the JSON for readability
    print(json.dumps(response_json, indent=2))
except urllib.error.HTTPError as e:
    # Handle HTTP errors
    print("Error code: %s" % e.code)
    print(e.read().decode('utf-8')) # Read and decode the error body
except urllib.error.URLError as e:
    # Handle URL errors
    print("Reason: %s" % e.reason

Key Differences in Python 3:

  • Imports: import urllib.request and import urllib.parse.
  • Encoding: urllib.parse.urlencode() is used. The resulting string is then encoded to bytes using .encode('utf-8') before being passed to the request. This is the standard way to handle data in Python 3.
  • Response Handling: response.read() returns bytes, so you must .decode() it to get a string (usually with utf-8).
  • Context Manager: Using with urllib.request.urlopen(...) as response: is a best practice. It ensures the network connection is closed automatically.

Important Recommendation: Use the requests Library

While the urllib library is built-in, the requests library is the de facto standard for making HTTP requests in Python. It is far more user-friendly, readable, and powerful.

Why use requests?

  • Simpler Syntax: The code is much cleaner and easier to read.
  • Automatic Decoding: It handles decoding response content (like JSON) automatically.
  • Better Session Management: Easily handle cookies and authentication.
  • Intuitive API: requests.get(), requests.post(), etc.

Here is the same task using the requests library (works for both Python 2 and 3 with minimal changes).

Using the requests Library

First, you need to install it:

pip install requests

requests Code

import requests
import json # For pretty printing
# The URL of the API endpoint
url = 'https://httpbin.org/post'
# The data you want to send as a dictionary
data = {
    'username': 'testuser',
    'password': 'secretpassword',
    'message': 'Hello from the requests library!'
}
# The headers dictionary
headers = {
    'User-Agent': 'Python-requests-Post-Example'
}
try:
    # requests.post() handles all the encoding and formatting for you!
    # You just pass the data dictionary directly.
    response = requests.post(url, data=data, headers=headers)
    # Raise an exception for bad status codes (4xx or 5xx)
    response.raise_for_status()
    # .json() is a handy helper that decodes the JSON response
    # into a Python dictionary. If the response isn't JSON, it will fail.
    response_json = response.json()
    print("--- Response Status Code ---")
    print(response.status_code)
    print("\n--- Response Headers ---")
    print(response.headers)
    print("\n--- Response Body (Pretty JSON) ---")
    print(json.dumps(response_json, indent=2))
except requests.exceptions.HTTPError as errh:
    print("Http Error:", errh)
except requests.exceptions.ConnectionError as errc:
    print("Error Connecting:", errc)
except requests.exceptions.Timeout as errt:
    print("Timeout Error:", errt)
except requests.exceptions.RequestException as err:
    print("Oops: Something Else", err)

As you can see, the requests version is significantly shorter and more intuitive. For any new project, strongly consider using requests.

Python urllib2如何实现POST请求?-图3
(图片来源网络,侵删)
分享:
扫描分享到社交APP
上一篇
下一篇