异步代码中URL重定向处理:grequests如何获取最终访问URL?
Absolutely possible! Let me break down how to handle redirects and grab the final URL with grequests—since it’s built on top of requests and gevent, we can reuse a lot of the familiar requests patterns with just a few small adjustments.
Quick Solution: Get the Final URL Directly
Just like with requests, grequests returns response objects that include a url attribute pointing to the final redirected address. Here’s how it works:
Requests Reference (for context)
import requests # Regular requests approach response = requests.get("http://example.com/redirect-target") final_url = response.url print(f"Final URL: {final_url}")
Grequests Equivalent
import grequests # Build the async request req = grequests.get("http://example.com/redirect-target", allow_redirects=True) # allow_redirects is True by default # Send the request and get the response response = grequests.map([req])[0] # Extract the final URL if the response is valid if response: final_url = response.url print(f"Final URL: {final_url}")
Track Full Redirect History
If you need to see every step of the redirect chain (not just the final URL), you can use the response.history attribute—just like in requests. This gives you a list of all prior response objects from each redirect.
import grequests def log_redirects(response, *args, **kwargs): if response.history: print("Redirect chain:") for i, redirect in enumerate(response.history): next_url = response.history[i+1].url if i+1 < len(response.history) else response.url print(f"Step {i+1}: {redirect.url} → {next_url}") # Add a hook to log redirects (optional but helpful) req = grequests.get("http://example.com/multi-step-redirect", hooks={"response": log_redirects}) response = grequests.map([req])[0] # Get the final URL if response: print(f"\nFinal URL: {response.url}")
Batch Requests Example
For multiple async requests, you can process all responses and extract their final URLs in one go:
import grequests # List of URLs that might redirect urls = [ "http://example.com/redirect-1", "http://example.com/redirect-2", "http://example.com/no-redirect" ] # Create async requests for all URLs requests = [grequests.get(url) for url in urls] # Send all requests and get responses responses = grequests.map(requests) # Iterate through responses to get final URLs for idx, resp in enumerate(responses): if resp: print(f"Original URL: {urls[idx]}") print(f"Final URL: {resp.url}\n") else: print(f"Request failed for {urls[idx]}\n")
Key Notes
allow_redirects=Trueis the default in grequests (just like requests), so you don’t need to specify it unless you want to disable redirects.- The response object from grequests is nearly identical to requests’ Response object—most attributes and methods you’re used to (like
url,history,status_code) work the same way.
内容的提问来源于stack exchange,提问作者game0ver

