mechanize nginx - 如何避免HTTP錯誤429(Too Many Requests)python



(5)

接收狀態429 不是錯誤 ,而是另一個服務器“請”請求您停止發送垃圾郵件請求。 顯然,您的請求率太高,服務器也不願意接受。

你不應該試圖“躲閃”這個,甚至試圖通過欺騙你的IP來繞過服務器安全設置,你應該通過不發送太多請求來尊重服務器的答案。

如果一切設置正確,您還將收到“Retry-after”標題以及429響應。 此標頭指定在進行另一次呼叫之前應等待的秒數。 處理這個“問題”的正確方法是讀取這個標題並讓你的過程睡了很多秒。

您可以在此處找到有關狀態429的更多信息: http://tools.ietf.org/html/rfc6585#page-3http://tools.ietf.org/html/rfc6585#page-3

我正在嘗試使用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")

正如MRA所說,你不應該試圖躲避429 Too Many Requests ,而是相應地處理它。 根據您的使用情況,您有多種選擇:

1) 睡覺你的過程 。 服務器通常在響應中包含Retry-after標頭,其中包含您在重試之前應等待的秒數。 請記住,睡眠過程可能會導致問題,例如在任務隊列中,您應該在以後重試任務以釋放工作人員以進行其他操作。

2) 指數退避 。 如果服務器沒有告訴您等待多長時間,則可以使用之間增加的暫停來重試您的請求。 流行的任務隊列Celery 內置了這個功能。

3) 令牌桶 。 如果您事先知道在給定時間內能夠進行多少次請求,則此技術非常有用。 每次訪問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()

編寫這段代碼修復了我的問題:

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


另一種解決方法是使用某種公共VPN或Tor網絡來欺騙您的IP。 這將假設IP級別的服務器上的速率限制。

有一篇簡短的博客文章演示了使用tor和urllib2的方法:

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


>>> from datetime import datetime
>>> datetime.now().strftime('%Y-%m-%d %H:%M:%S')

對於這個例子,輸出將是這樣的: '2013-09-18 11:16:32'

這是strftime的列表。





python http mechanize