Saya mencoba menggunakan Python untuk masuk ke situs web dan mengumpulkan informasi dari beberapa halaman web dan saya mendapatkan kesalahan berikut:
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
Saya menggunakan time.sleep()
dan berfungsi, tetapi tampaknya tidak cerdas dan tidak dapat diandalkan, apakah ada cara lain untuk menghindari kesalahan ini?
Ini kode saya:
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")
python
http
mechanize
http-status-code-429
Aous1000
sumber
sumber
sleep
.Jawaban:
Menerima status 429 bukanlah suatu kesalahan , itu adalah server lain yang "dengan hormat" meminta Anda untuk menghentikan permintaan spamming. Jelasnya, tingkat permintaan Anda terlalu tinggi dan server tidak mau menerimanya.
Anda tidak boleh berusaha untuk "mengelak" ini, atau bahkan mencoba mengelak dari pengaturan keamanan server dengan mencoba menipu IP Anda, Anda harus menghormati jawaban server dengan tidak mengirimkan terlalu banyak permintaan.
Jika semuanya sudah diatur dengan benar, Anda juga akan menerima header "Retry-after" bersama dengan respon 429. Header ini menentukan berapa detik Anda harus menunggu sebelum melakukan panggilan lain. Cara yang tepat untuk menangani "masalah" ini adalah dengan membaca tajuk ini dan menghentikan proses Anda selama beberapa detik.
Anda dapat menemukan informasi lebih lanjut tentang status 429 di sini: http://tools.ietf.org/html/rfc6585#page-3
sumber
HTTPError as my_exception
, itu tersedia dimy_exception.headers
, setidaknya untuk urllib2.Menulis kode ini memperbaiki masalah saya:
requests.get(link, headers = {'User-agent': 'your bot 0.1'})
sumber
Seperti yang dikatakan Penilaian Multi Penilai, Anda tidak boleh mencoba mengelak,
429 Too Many Requests
tetapi menanganinya dengan tepat. Anda memiliki beberapa opsi tergantung pada kasus penggunaan Anda:1) Tidur proses Anda . Server biasanya menyertakan
Retry-after
tajuk dalam respons dengan jumlah detik yang seharusnya Anda tunggu sebelum mencoba lagi. Ingatlah bahwa menghentikan proses dapat menyebabkan masalah, misalnya dalam antrian tugas, di mana Anda harus mencoba ulang tugas di lain waktu untuk membebaskan pekerja dari hal-hal lain.2) Kemunduran eksponensial . Jika server tidak memberi tahu Anda berapa lama harus menunggu, Anda dapat mencoba kembali permintaan Anda menggunakan jeda yang meningkat di antaranya. Tugas populer antrian Seledri memiliki fitur ini dibangun tepat-in .
3) Ember token . Teknik ini berguna jika Anda mengetahui sebelumnya berapa banyak permintaan yang dapat Anda buat dalam waktu tertentu. Setiap kali Anda mengakses API, pertama-tama Anda mengambil token dari bucket. Ember diisi ulang dengan kecepatan konstan. Jika keranjang kosong, Anda harus menunggu sebelum membuka API lagi. Keranjang token biasanya diterapkan di ujung lain (API) tetapi Anda juga dapat menggunakannya sebagai proxy untuk menghindari mendapatkan file
429 Too Many Requests
. Fitur rate_limit Celery menggunakan algoritma ember token.Berikut adalah contoh aplikasi Python / Celery yang menggunakan backoff eksponensial dan bucket rate-limiting / token:
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()
sumber
Solusi lain adalah memalsukan IP Anda menggunakan semacam VPN Publik atau jaringan Tor. Ini akan mengasumsikan pembatasan kecepatan pada server pada tingkat IP.
Ada posting blog singkat yang mendemonstrasikan cara menggunakan tor bersama dengan urllib2:
http://blog.flip-edesign.com/?p=119
sumber
if response.status_code == 429: time.sleep(int(response.headers["Retry-After"]))
sumber
Saya telah menemukan solusi yang bagus untuk pemblokiran IP saat mengorek situs. Ini memungkinkan Anda menjalankan Scraper tanpa batas waktu dengan menjalankannya dari Google App Engine dan menerapkannya kembali secara otomatis saat Anda mendapatkan 429.
Lihat artikel ini
sumber