programing

HTTP 오류 429(Too Many Requests) 파이썬을 방지하는 방법

oldcodes 2023. 7. 18. 21:56
반응형

HTTP 오류 429(Too Many Requests) 파이썬을 방지하는 방법

Python을 사용하여 웹 사이트에 로그인하고 여러 웹 페이지에서 정보를 수집하려고 하면 다음 오류가 발생합니다.

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")

상태 429를 수신하는 것은 오류가 아닙니다. 스팸 발송 요청을 중지하도록 요청하는 것은 다른 서버입니다.요청 비율이 너무 높아 서버가 이를 수락하지 않을 것임이 분명합니다.

이 문제를 "회피"하려고 하거나 IP를 스푸핑하여 서버 보안 설정을 회피하려고 해서는 안 됩니다. 너무 많은 요청을 보내지 않음으로써 서버의 응답을 존중해야 합니다.

모든 것이 올바르게 설정된 경우, 429 응답과 함께 "Retry-after" 헤더도 수신됩니다.이 헤더는 다른 전화를 걸기 전에 기다려야 하는 시간(초)을 지정합니다.이 "문제"를 처리하는 적절한 방법은 이 헤더를 읽고 프로세스를 몇 초 동안 절전 모드로 전환하는 것입니다.

상태 429에 대한 자세한 내용은 https://www.rfc-editor.org/rfc/rfc6585#page-3 에서 확인할 수 있습니다.

요청 시 이 코드를 작성하여 문제 해결:

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

사용자 에이전트가 제공되지 않은 경우 사이트에서 Too Many Requests(429) 오류를 반환하는 경우가 있기 때문에 이 문제가 해결됩니다.예를 들어, Reddit의 API는 사용자 에이전트가 적용될 때만 작동합니다.

MRA가 말했듯이, 당신은 피하려고 해서는 안 됩니다.429 Too Many Requests대신 그에 따라 처리합니다.사용 사례에 따라 몇 가지 옵션이 있습니다.

프로세스를 절전 모드로 전환합니다.서버에는 일반적으로 다음이 포함됩니다.Retry-after다시 시도하기 전에 대기해야 하는 시간(초)이 포함된 응답의 헤더입니다.프로세스를 절전 모드로 전환하면 작업 대기열 등에서 문제가 발생할 수 있으므로 나중에 작업자가 다른 작업을 수행할 수 있도록 작업을 다시 시도해야 합니다.

기하급수적인 후퇴.서버가 대기 시간을 알려주지 않을 경우, 간격을 늘려서 요청을 다시 시도할 수 있습니다.인기 작업 대기열인 셀러리에는 이 기능이 내장되어 있습니다.

토큰 버킷.이 기술은 주어진 시간에 요청할 수 있는 수를 미리 알고 있는 경우 유용합니다.API에 액세스할 때마다 먼저 버킷에서 토큰을 가져옵니다.버킷은 일정한 속도로 리필됩니다.버킷이 비어 있으면 API를 다시 실행하기 전에 기다려야 합니다.토큰 버킷은 일반적으로 다른 쪽 끝(API)에서 구현되지만, 이를 프록시로 사용하여 다음을 방지할 수도 있습니다.429 Too Many RequestsCelery의 rate_limit 기능은 토큰 버킷 알고리즘을 사용합니다.

다음은 지수 백오프 및 속도 제한/토큰 버킷을 사용하는 Python/Celery 앱의 예입니다.

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()
if response.status_code == 429:
  time.sleep(int(response.headers["Retry-After"]))

또 다른 해결 방법은 일종의 공용 VPN 또는 Tor 네트워크를 사용하여 IP를 스푸핑하는 것입니다.이는 IP 수준에서 서버의 속도 제한을 가정한 것입니다.

urllib2와 함께 tor를 사용하는 방법을 보여주는 간단한 블로그 게시물이 있습니다.

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

저는 사이트를 스크랩할 때 IP 차단에 대한 좋은 해결책을 찾았습니다.Google App Engine에서 Scraper를 실행하고 429를 받으면 자동으로 다시 배포하여 Scraper를 무기한 실행할 수 있습니다.

기사를 확인하십시오.

대부분의 경우 서버가 사용자에게 데이터 삭제를 요청하더라도 웹 사이트에서 데이터를 계속 삭제하는 것은 비윤리적입니다.그러나 그렇지 않은 경우에는 공용 프록시 목록을 사용하여 다양한 IP 주소를 가진 웹 사이트를 스크랩할 수 있습니다.

언급URL : https://stackoverflow.com/questions/22786068/how-to-avoid-http-error-429-too-many-requests-python

반응형