क्या अजगर में एक URL का अनुरोध करने और पुनर्निर्देश का पालन नहीं करने का एक आसान तरीका है?


96

Urllib2 के स्रोत को देखकर ऐसा लगता है कि ऐसा करना सबसे आसान तरीका है HTTPRedirectHandler को उपवर्गित करें और फिर HTTP_edirectHandler को ओवरराइड करने के लिए build_opener का उपयोग करें, लेकिन ऐसा लगता है कि ऐसा बहुत (अपेक्षाकृत जटिल) काम करने के लिए होता है जो ऐसा होना चाहिए जैसा लगता है बहुत साधारण।


2
गोगलर्स के लिए: अनुरोध लाइब्रेरी का उपयोग करने से आपको बहुत अधिक सिरदर्द से बचाएंगे : docs.python-requests.org और नीचे मैरियन का उत्तर देखें, यह बहुत ही सुंदर है।
आलोकज जनेज

मैं मानता हूं कि अनुरोध इन दिनों जाने का रास्ता है। मैंने इस टिप्पणी और मारियन के उत्तर को अपदस्थ कर दिया है, लेकिन मैं उत्तर छोड़ रहा हूं क्योंकि यह उस समय सर्वश्रेष्ठ था।
जॉन

1
@ जॉन पुरस्कार अच्छे हैं लेकिन समय आगे बढ़ता है और यह एक सामुदायिक संपादित साइट है। ध्यान अच्छे उत्तरों पर है न कि लोगों पर। वह अपने उत्थान के बिंदु रखेगा। आप अपठित पुस्तकालयों में साथी कोडर के भ्रामक टन कर रहे हैं।
mit

1
ठीक है पर्याप्त ठीक है। मैंने अनुरोधों को स्वीकार कर लिया है।
जॉन

जवाबों:


180

यहाँ अनुरोध तरीका है:

import requests
r = requests.get('http://github.com', allow_redirects=False)
print(r.status_code, r.headers['Location'])

5
फिर r.headers['Location']यह देखने के लिए कि उसने आपको कहाँ भेजा होगा
patricksurry

ध्यान दें कि ऐसा लगता है कि अनुरोध सामान्य Locationहो जाएंगे location
हमीश

2
@ हमेश requestsआपको हेडर को विहित रूप में और लोअरकेस में एक्सेस करने की अनुमति देता है। Docs.python-requests.org/en/master/user/quickstart/…
मैरियन

1
पायथन 3 में 2019 तक, यह अब मेरे लिए काम नहीं करता है। (मुझे एक प्रमुख तानाशाह त्रुटि मिलती है।)
मैक्स वॉन हिप्पेल

35

डाइव इनटू पायथन में urllib2 के साथ रीडायरेक्ट को संभालने का एक अच्छा अध्याय है। एक और समाधान हैप्लासिब

>>> import httplib
>>> conn = httplib.HTTPConnection("www.bogosoft.com")
>>> conn.request("GET", "")
>>> r1 = conn.getresponse()
>>> print r1.status, r1.reason
301 Moved Permanently
>>> print r1.getheader('Location')
http://www.bogosoft.com/new/location

7
Google से यहां आने वाला हर व्यक्ति, कृपया ध्यान दें कि जाने का तरीका अप करने के लिए यह एक है: stackoverflow.com/a/14678220/362951 अनुरोध पुस्तकालय आपको बहुत सारे सिरदर्द से बचाएगा।
mit

"डाइव इनटू पायथन" की कड़ी मर चुकी है।
गुत्थी

11

यह एक urllib2 हैंडलर है जो पुनर्निर्देश का पालन नहीं करेगा:

class NoRedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_302(self, req, fp, code, msg, headers):
        infourl = urllib.addinfourl(fp, headers, req.get_full_url())
        infourl.status = code
        infourl.code = code
        return infourl
    http_error_300 = http_error_302
    http_error_301 = http_error_302
    http_error_303 = http_error_302
    http_error_307 = http_error_302

opener = urllib2.build_opener(NoRedirectHandler())
urllib2.install_opener(opener)

मैं एक एपीआई का परीक्षण कर रहा हूं और एक लॉगिन विधि के साथ काम कर रहा हूं जो उस पृष्ठ पर रीडायरेक्ट करता है जिसकी मुझे परवाह नहीं है, लेकिन रीडायरेक्ट की प्रतिक्रिया के साथ वांछित सत्र कुकी नहीं भेजता है। यह वही है जो मुझे उसके लिए चाहिए था।
टिम वाइल्डर

9

redirectionsमें कीवर्ड httplib2अनुरोध विधि एक रेड हेरिंग है। पहला अनुरोध वापस करने के बजाय RedirectLimitयदि यह पुनर्निर्देशन स्थिति कोड प्राप्त करता है तो यह एक अपवाद को बढ़ाएगा । वस्तु पर सेट follow_redirectsकरने के लिए आपको इनहिटल प्रतिक्रिया देने के लिए :FalseHttp

import httplib2
h = httplib2.Http()
h.follow_redirects = False
(response, body) = h.request("http://example.com")

8

मुझे लगता है कि इससे मदद मिलेगी

from httplib2 import Http
def get_html(uri,num_redirections=0): # put it as 0 for not to follow redirects
conn = Http()
return conn.request(uri,redirections=num_redirections)

5

मैं पायथन में गोता लगाने के लिए ओल्ट का दूसरा सूचक हूं । यहां urllib2 रीडायरेक्ट हैंडलर का उपयोग करते हुए एक कार्यान्वयन है, इससे अधिक काम होना चाहिए? हो सकता है, श्रग।

import sys
import urllib2

class RedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_301(self, req, fp, code, msg, headers):  
        result = urllib2.HTTPRedirectHandler.http_error_301( 
            self, req, fp, code, msg, headers)              
        result.status = code                                 
        raise Exception("Permanent Redirect: %s" % 301)

    def http_error_302(self, req, fp, code, msg, headers):
        result = urllib2.HTTPRedirectHandler.http_error_302(
            self, req, fp, code, msg, headers)              
        result.status = code                                
        raise Exception("Temporary Redirect: %s" % 302)

def main(script_name, url):
   opener = urllib2.build_opener(RedirectHandler)
   urllib2.install_opener(opener)
   print urllib2.urlopen(url).read()

if __name__ == "__main__":
    main(*sys.argv) 

3
गलत लगता है ... यह कोड वास्तव में पुनर्निर्देश का पालन करता है (मूल हैंडलर को कॉल करके, इस प्रकार एक HTTP अनुरोध जारी करता है), और फिर एक अपवाद
उठाएं

5

हालांकि सबसे छोटा रास्ता है

class NoRedirect(urllib2.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, hdrs, newurl):
        pass

noredir_opener = urllib2.build_opener(NoRedirect())

1
यह सबसे छोटा तरीका कैसे है? इसमें आयात या वास्तविक अनुरोध भी शामिल नहीं है।
मरिअन

मैं पहले से ही इस समाधान को पोस्ट करने जा रहा था और नीचे इस जवाब को पाकर काफी हैरान था। यह बहुत संक्षिप्त है और मेरी राय में शीर्ष उत्तर होना चाहिए।
उपयोगकर्ता

इसके अलावा, यह आपको अधिक स्वतंत्रता देता है, इस तरह से यह नियंत्रित करना संभव है कि कौन से URL का अनुसरण करना है
उपयोगकर्ता

मैं पुष्टि करता हूं, यह आसान तरीका है। उन लोगों के लिए एक छोटी टिप्पणी जो डिबग करना चाहते हैं। यह मत भूलो कि आप सलामी बल्लेबाज को बुलाने पर हैंडलर सेट कर सकते हैं जैसे: opener = urllib.request.build_opener(debugHandler, NoRedirect())कहां debugHandler=urllib.request.HTTPHandler()और कहां debugHandler.set_http_debuglevel (1)। अंत में:urllib.request.install_opener(opener)
StashOfCode
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.