HTTP त्रुटि 429 (बहुत अनुरोध) से कैसे बचें


93

मैं एक वेबसाइट पर लॉगिन करने और कई वेबपेजों से जानकारी इकट्ठा करने के लिए पायथन का उपयोग करने की कोशिश कर रहा हूं और मुझे निम्नलिखित त्रुटि मिलती है:

Traceback (most recent call last):
  File "extract_test.py", line 43, in <module>
    response=br.open(v)
  File "/usr/local/lib/python2.7/dist-packages/mechanize/_mechanize.py", line 203, in open
    return self._mech_open(url, data, timeout=timeout)
  File "/usr/local/lib/python2.7/dist-packages/mechanize/_mechanize.py", line 255, in _mech_open
    raise response
mechanize._response.httperror_seek_wrapper: HTTP Error 429: Unknown Response Code

मैंने उपयोग किया time.sleep()और यह काम करता है, लेकिन यह अनजाने और अविश्वसनीय लगता है, क्या इस त्रुटि को चकमा देने का कोई और तरीका है?

यहाँ मेरा कोड है:

import mechanize
import cookielib
import re
first=("example.com/page1")
second=("example.com/page2")
third=("example.com/page3")
fourth=("example.com/page4")
## I have seven URL's I want to open

urls_list=[first,second,third,fourth]

br = mechanize.Browser()
# Cookie Jar
cj = cookielib.LWPCookieJar()
br.set_cookiejar(cj)

# Browser options 
br.set_handle_equiv(True)
br.set_handle_redirect(True)
br.set_handle_referer(True)
br.set_handle_robots(False)

# Log in credentials
br.open("example.com")
br.select_form(nr=0)
br["username"] = "username"
br["password"] = "password"
br.submit()

for url in urls_list:
        br.open(url)
        print re.findall("Some String")

6
इसके आस-पास कोई रास्ता नहीं है, यह सर्वर-साइड पर एक प्रवर्तन है जो आपके द्वारा किए गए कितने अनुरोधों / समय-इकाई का ट्रैक रखता है। यदि आप इस इकाई को पार करते हैं तो आप अस्थायी रूप से अवरुद्ध हो जाएंगे। कुछ सर्वर हेडर में यह जानकारी भेजते हैं, लेकिन वे अवसर दुर्लभ हैं। सर्वर से प्राप्त हेडर की जाँच करें, उपलब्ध जानकारी का उपयोग करें .. यदि नहीं, तो जाँच करें कि आप कितनी तेजी से बिना पकड़े जा सकते हैं और उपयोग कर सकते हैं sleep
Torxed

जवाबों:


158

एक स्थिति 429 प्राप्त करना एक त्रुटि नहीं है , यह दूसरा सर्वर "कृपया" है जो आपसे स्पैमिंग अनुरोधों को रोकने के लिए कहता है। जाहिर है, आपके अनुरोधों की दर बहुत अधिक है और सर्वर इसे स्वीकार करने को तैयार नहीं है।

आपको इसे "चकमा" नहीं देना चाहिए, या यहां तक ​​कि अपने आईपी को खराब करने की कोशिश करके सर्वर सुरक्षा सेटिंग्स को दरकिनार करने की कोशिश करनी चाहिए, आपको बस बहुत सारे अनुरोध न भेजकर सर्वर के जवाब का सम्मान करना चाहिए।

यदि सब कुछ ठीक से सेट किया गया है, तो आपको 429 प्रतिक्रिया के साथ "रिट्री-आफ्टर" हेडर भी प्राप्त होगा। यह हेडर सेकंड की संख्या निर्दिष्ट करता है जिसे आपको दूसरा कॉल करने से पहले इंतजार करना चाहिए। इस "समस्या" से निपटने का उचित तरीका है कि आप इस हेडर को पढ़ें और अपनी प्रक्रिया को कई सेकंड तक सोएँ।

आप स्थिति 429 पर अधिक जानकारी यहाँ से प्राप्त कर सकते हैं: http://tools.ietf.org/html/rfc6585#page-3


23
खैर, किसी ने कभी नहीं कहा कि सभी वेब सर्वर सही तरीके से कॉन्फ़िगर किए गए हैं। इसके अलावा, चूंकि अधिकांश दर सीमाएं आईपी द्वारा आगंतुकों की पहचान कर रही हैं, इसलिए यह उस परिदृश्य में समस्याओं का कारण बन सकता है जहां आईपी को गतिशील रूप से साझा किया जाता है। यदि आप स्थिति 429 प्राप्त करते रहते हैं, हालांकि आप आश्वस्त हैं कि आपने बहुत सारे अनुरोध नहीं भेजे हैं, तो आप साइट के व्यवस्थापक से संपर्क करने पर विचार कर सकते हैं।
एमआरए

2
"रिट्री-आफ्टर" हेडर का उल्लेख करने के लिए धन्यवाद। मुझे यह देखने के लिए एक कोड उदाहरण पसंद आएगा कि उस मूल्य को कैसे प्राप्त किया जाए (मैं urllib का उपयोग कर रहा था, ओपी मैकेनाइज करने के लिए, या तो मुझे नहीं लगता कि हेडर को उठाए गए अपवाद में शामिल किया गया है)
MacFreek

@MacFreek में मेरे पास कोई विशेष पायथन कोड उदाहरण तैयार नहीं है, लेकिन मैं कुछ उदाहरणों के बारे में मानता हूं कि सामान्य रूप से प्रतिक्रिया हेडर कैसे प्राप्त करें इस प्रश्न के उत्तर से लिया जा सकता है: stackoverflow.com/q/843392
MRA

धन्यवाद @ एमआरए मैंने पाया कि हेडर अपवाद में भी उपलब्ध हैं: पकड़ने के बाद HTTPError as my_exception, यह my_exception.headersकम से कम urllib2 में उपलब्ध है ।
मैकफ्रिक

38

इस कोड को लिखने से मेरी समस्या ठीक हो गई:

requests.get(link, headers = {'User-agent': 'your bot 0.1'})


26
यह उत्तर अस्वीकृत है, लेकिन कुछ साइटें स्वचालित रूप से त्रुटि कोड 429 लौटाती हैं यदि उपयोगकर्ता एजेंट अन्य लोगों से दुर्व्यवहार के कारण प्रतिबंधित है। यदि आपको त्रुटि कोड 429 मिलता है, भले ही आपने केवल कुछ अनुरोध भेजे हों, तो उपयोगकर्ता एजेंट को किसी अन्य चीज़ पर सेट करने का प्रयास करें।
फेरी बेंडर

7
जोड़ना भी चाहेंगे, कुछ साइटें स्पष्ट रूप से अनुरोधों को अस्वीकार कर देती हैं जब तक कि उपयोगकर्ता-एजेंट नहीं भेजा जाता है, और आपको अन्य प्रतिक्रियाओं का असंख्य मिल सकता है: 503/403 / कुछ सामान्य सूचकांक पृष्ठ।
user3791372

1
इसकी पुष्टि कर सकते हैं। बस Reddit के साथ अजगर को इंटरफ़ेस करने की कोशिश कर रहा हूं और उपयोगकर्ता एजेंट को सेट किए बिना मुझे हमेशा त्रुटि कोड 429 मिल रहा था।
कार्तिक

1
क्या आप कृपया कुछ स्पष्टीकरण जोड़ सकते हैं?
तोकसी

आप "कोड का यह टुकड़ा" कहाँ लिखते हैं? इस समाधान के लिए अधिक विवरण की आवश्यकता है।
जो मैक्लीन

29

जैसा कि MRA ने कहा, आपको चकमा देने की कोशिश नहीं करनी चाहिए 429 Too Many Requests इसके बजाय, लेकिन इसके बजाय इसे संभालने की । आपके उपयोग-मामले के आधार पर आपके पास कई विकल्प हैं:

1) अपनी प्रक्रिया को सो जाओ । सर्वर में आम तौर पर एक शामिल होता हैRetry-after शीर्षलेख होता है, जिसकी संख्या सेकंड में होती है जिसे आप पुनः प्रयास करने से पहले प्रतीक्षा करने वाले होते हैं। ध्यान रखें कि एक प्रक्रिया के दौरान नींद की समस्या हो सकती है, उदाहरण के लिए, कार्य कतार में, जहां आपको बाद में कार्य को फिर से करना चाहिए ताकि अन्य चीजों के लिए कार्यकर्ता को मुक्त किया जा सके।

2) घातीय बैकऑफ़ । यदि सर्वर आपको यह नहीं बताता है कि कब तक इंतजार करना है, तो आप बीच-बीच में बढ़ते हुए ठहराव का उपयोग करके अपने अनुरोध को पुनः प्राप्त कर सकते हैं। लोकप्रिय कार्य कतार सेलेरी में यह सुविधा राइट-इन निर्मित है

3) टोकन बाल्टी । यह तकनीक उपयोगी है यदि आप पहले से जानते हैं कि आप किसी निश्चित समय में कितने अनुरोध करने में सक्षम हैं। हर बार जब आप एपीआई का उपयोग करते हैं तो आप पहले बाल्टी से टोकन प्राप्त करते हैं। बाल्टी को एक स्थिर दर पर रिफिल किया जाता है। अगर बाल्टी खाली है, तो आप जानते हैं कि एपीआई को फिर से मारने से पहले आपको इंतजार करना होगा। टोकन बाल्टी आमतौर पर दूसरे छोर (एपीआई) पर लागू की जाती है, लेकिन आप कभी भी एक से बचने के लिए प्रॉक्सी के रूप में उनका उपयोग कर सकते हैं 429 Too Many Requests। अजवाइन का दर_लमिट फ़ीचर में एक टोकन बकेट एल्गोरिदम का उपयोग किया गया है।

यहाँ घातीय बैकऑफ़ और दर-सीमित / टोकन बाल्टी का उपयोग करते हुए पायथन / सेलेरी ऐप का एक उदाहरण दिया गया है:

class TooManyRequests(Exception):
"""Too many requests"""

@task(
   rate_limit='10/s',
   autoretry_for=(ConnectTimeout, TooManyRequests,),
   retry_backoff=True)
def api(*args, **kwargs):
  r = requests.get('placeholder-external-api')

  if r.status_code == 429:
    raise TooManyRequests()

9

सार्वजनिक वीपीएन या टोर नेटवर्क के कुछ प्रकार का उपयोग करके अपने आईपी को खराब करने के लिए एक और समाधान होगा। यह आईपी स्तर पर सर्वर पर रेट-लिमिटिंग माना जाएगा।

एक संक्षिप्त ब्लॉग पोस्ट है जिसमें urllib2 के साथ टोर का उपयोग करने का तरीका दिखाया गया है:

http://blog.flip-edesign.com/?p=119


8
यही कारण है कि मुझे हमेशा अनुरोध करने के लिए कुंजी के लिए पंजीकरण करने के लिए अपने एपीआई के उपयोगकर्ताओं की आवश्यकता होती है। इस तरह से मैं आईपी के बजाय कुंजी द्वारा अनुरोधों को सीमित कर सकता हूं। दूसरी कुंजी के लिए पंजीकरण करना एक उच्च सीमा प्राप्त करने का एकमात्र तरीका होगा।
Mnebuerquo

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.