杰瑞科技汇

Python requests 302重定向如何处理?

Of course. The 302 Found HTTP status code is a fundamental concept in web browsing and API interaction, and the requests library in Python handles it in a specific way.

Python requests 302重定向如何处理?-图1
(图片来源网络,侵删)

Here's a comprehensive guide covering what a 302 is, how requests deals with it by default, and how to control its behavior.


What is a 302 Redirect?

A 302 Found (also known as a "temporary redirect") is an HTTP response status code that tells the client (your Python script) that the resource it requested has been temporarily moved to a different URL.

  • Purpose: The server is saying, "The thing you asked for isn't here right now, but you can find it at this other address. Please use that new address for this request only."
  • Key Characteristic: It's temporary. The server expects the client to continue using the original URL for future requests.

How requests Handles 302 by Default

The requests library is designed to behave like a web browser. By default, it is configured to follow redirects automatically.

This means if you send a request to a URL that returns a 302 status code, requests will:

Python requests 302重定向如何处理?-图2
(图片来源网络,侵删)
  1. Receive the 302 response.
  2. Automatically see the Location header in the response, which contains the new URL.
  3. Send a new GET request to that Location URL.
  4. Return the response from this final, successful request to you.

The Response object you get back will contain the content, headers, and status code of the final destination, not the original 302 redirect.

Example: Default Behavior (Following Redirects)

Let's use httpbin.org, a fantastic service for testing HTTP requests. It has an endpoint that returns a 302 redirect.

import requests
# The URL that will give us a 302 redirect
url = "http://httpbin.org/redirect/1" # This will redirect to http://httpbin.org/get
try:
    # By default, allow_redirects=True
    response = requests.get(url)
    print(f"Original URL: {url}")
    print("-" * 30)
    # The response object is for the FINAL destination
    print(f"Final URL: {response.url}")
    print(f"Final Status Code: {response.status_code}")
    print(f"History (shows redirects): {response.history}")
    # The history attribute is a list of Response objects from the intermediate redirects
    if response.history:
        print("\nRedirect chain:")
        for r in response.history:
            print(f"  - Redirected from {r.url} with status {r.status_code}")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Output:

Original URL: http://httpbin.org/redirect/1
------------------------------
Final URL: http://httpbin.org/get
Final Status Code: 200
History (shows redirects): [<Response [302]>]
Redirect chain:
  - Redirected from http://httpbin.org/redirect/1 with status 302

As you can see:

Python requests 302重定向如何处理?-图3
(图片来源网络,侵删)
  • response.url is the final URL (http://httpbin.org/get).
  • response.status_code is 200 (OK), not 302.
  • response.history contains a list of the intermediate redirect responses.

How to Control Redirect Behavior

Sometimes, you don't want requests to follow redirects automatically. The most common reason is to inspect the redirect itself—to see the Location header or check the original 302 status code.

You can disable this behavior using the allow_redirects parameter.

Example: Disabling Redirects

Set allow_redirects=False in your request. requests will stop and return the 302 response immediately.

import requests
url = "http://httpbin.org/redirect/1"
try:
    # Set allow_redirects=False to stop at the 302
    response = requests.get(url, allow_redirects=False)
    print(f"Original URL: {url}")
    print("-" * 30)
    # The response object is now for the ORIGINAL request
    print(f"Final URL: {response.url}") # Still the original URL
    print(f"Status Code: {response.status_code}") # This will be 302!
    # The Location header contains the URL we would have been redirected to
    print(f"Location Header: {response.headers.get('Location')}")
    # History will be empty because we didn't follow any redirects
    print(f"History: {response.history}")
except requests.exceptions.RequestException as e:
    print(f"An error occurred: {e}")

Output:

Original URL: http://httpbin.org/redirect/1
------------------------------
Final URL: http://httpbin.org/redirect/1
Status Code: 302
Location Header: http://httpbin.org/get
History: []

This is incredibly useful for debugging or for applications that need to handle redirects manually.


Other Important Redirect Status Codes

While you asked about 302, it's good to know that requests handles them all with the same allow_redirects logic:

  • 301 Moved Permanently: A permanent redirect. requests follows it by default. Browsers often cache this, so they will directly request the new URL in the future without asking the server again.
  • 302 Found: A temporary redirect. The default behavior for requests.
  • 303 See Other: The response to the request can be found under a different URI and should be retrieved using a GET method. requests handles this correctly by changing the method to GET for the subsequent request.
  • 307 Temporary Redirect: Very similar to 302, but it specifies that the request method (e.g., POST) and body must not be changed when redirecting. requests respects this.
  • 308 Permanent Redirect: The permanent equivalent of 307. The method and body are not changed, and the redirect is permanent.

Summary Table

Parameter Value Behavior Use Case
allow_redirects True (Default) requests automatically follows 302, 301, 303, 307, 308 redirects. The final response is returned. Most common use cases. You want the data from the final destination, like a user clicking a link.
allow_redirects False requests stops at the first redirect (e.g., 302). The intermediate response (with the 302 status) is returned. Debugging, checking the Location header, or implementing custom redirect logic.

Final Recommendation

  • For 99% of cases: Use the default allow_redirects=True. It's what you want when you're just trying to get data from a URL that might have moved.
  • When you need to debug or handle redirects manually: Use allow_redirects=False to inspect the redirect headers and status codes before deciding how to proceed.
分享:
扫描分享到社交APP
上一篇
下一篇