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 Requests
Celery의 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
'programing' 카테고리의 다른 글
숫자처럼 보이는 것을 인덱싱할 때 파이썬의 "세 개의 점"은 무엇을 의미합니까? (0) | 2023.07.18 |
---|---|
JDBC를 사용하여 Oracle에 연결하기 위해 자격 증명 저장을 피하는 방법은 무엇입니까? (0) | 2023.07.18 |
Java에서 Closeable 인터페이스의 Close() 메서드의 동일성은 어떻게 보장됩니까? (0) | 2023.07.18 |
python의 속성 파일(Java Properties와 유사) (0) | 2023.07.18 |
대본 끝에 R이 삐/삐 소리를 낼 수 있는 방법이 있나요? (0) | 2023.07.18 |