Saya mengumpulkan statistik pada daftar situs web dan saya menggunakan permintaan untuk kesederhanaan. Ini kode saya:
data=[]
websites=['http://google.com', 'http://bbc.co.uk']
for w in websites:
r= requests.get(w, verify=False)
data.append( (r.url, len(r.content), r.elapsed.total_seconds(), str([(l.status_code, l.url) for l in r.history]), str(r.headers.items()), str(r.cookies.items())) )
Sekarang, saya ingin requests.get
timeout setelah 10 detik sehingga loop tidak macet.
Pertanyaan ini telah menarik sebelumnya juga tetapi tidak ada jawaban yang bersih. Saya akan memberikan beberapa hadiah untuk mendapatkan jawaban yang bagus.
Saya mendengar bahwa mungkin tidak menggunakan permintaan adalah ide yang baik tetapi kemudian bagaimana saya harus mendapatkan penawaran hal-hal baik yang ditawarkan. (yang ada di tuple)
python
timeout
python-requests
Kiarash
sumber
sumber
Jawaban:
Bagaimana dengan menggunakan eventlet? Jika Anda ingin menghentikan permintaan setelah 10 detik, meskipun data sedang diterima, cuplikan ini akan berfungsi untuk Anda:
sumber
eventlet.monkey_patch()
wajib?socket
modul perlu ditambal monyet, jadi setidaknya Anda akan membutuhkaneventlet.monkey_patch(socket=True)
requests.get('https://github.com', timeout=5)
Setel parameter batas waktu :
Selama Anda tidak menetapkan
stream=True
permintaan itu, ini akan menyebabkan panggilan kerequests.get()
timeout jika koneksi membutuhkan waktu lebih dari sepuluh detik, atau jika server tidak mengirim data selama lebih dari sepuluh detik.sumber
UPDATE: https://requests.readthedocs.io/en/master/user/advanced/#timeouts
Dalam versi baru
requests
:Jika Anda menentukan nilai tunggal untuk batas waktu, seperti ini:
Nilai batas waktu akan diterapkan untuk batas waktu
connect
danread
batas waktu. Tentukan tuple jika Anda ingin mengatur nilai secara terpisah:Jika server jarak jauh sangat lambat, Anda dapat memberi tahu Permintaan untuk menunggu selamanya untuk tanggapan, dengan melewatkan None sebagai nilai batas waktu dan kemudian mengambil secangkir kopi.
Jawaban lama saya (mungkin kedaluwarsa) (yang sudah diposting sebelumnya):
Ada cara lain untuk mengatasi masalah ini:
1. Gunakan
TimeoutSauce
kelas internalDari: https://github.com/kennethreitz/requests/issues/1928#issuecomment-35811896
2. Gunakan garpu permintaan dari kevinburke: https://github.com/kevinburke/requests/tree/connect-timeout
Dari dokumentasinya: https://github.com/kevinburke/requests/blob/connect-timeout/docs/user/advanced.rst
kevinburke telah memintanya untuk bergabung ke dalam proyek permintaan utama, tetapi belum diterima.
sumber
this won't work for you use-case
. Maksudnya itu tidak bekerja dengan aliran mp3 yang diinginkan oleh orang lain.timeout = int(seconds)
Karena
requests >= 2.4.0
, Anda dapat menggunakantimeout
argumen, yaitu:catatan:
sumber
Untuk membuat batas waktu Anda dapat menggunakan sinyal .
Cara terbaik untuk menyelesaikan kasus ini mungkin
try-except-finally
blok.Berikut ini beberapa contoh kode:
Ada beberapa peringatan untuk ini:
Tapi, itu semua ada di pustaka python standar! Kecuali untuk impor fungsi tidur, itu hanya satu impor. Jika Anda akan menggunakan waktu habis banyak tempat Anda dapat dengan mudah menempatkan TimeoutException, _timeout dan bernyanyi dalam suatu fungsi dan panggil saja. Atau Anda dapat membuat dekorator dan menjalankan fungsinya, lihat jawabannya di bawah ini.
Anda juga dapat mengatur ini sebagai "manajer konteks" sehingga Anda dapat menggunakannya dengan
with
pernyataan:Satu kemungkinan kelemahan dari pendekatan manajer konteks ini adalah bahwa Anda tidak dapat mengetahui apakah kode tersebut benar-benar kehabisan waktu atau tidak.
Sumber dan bacaan yang direkomendasikan:
sumber
Coba permintaan ini dengan penanganan batas waktu & kesalahan:
sumber
Atur
stream=True
dan gunakanr.iter_content(1024)
. Ya,eventlet.Timeout
entah bagaimana tidak berhasil untuk saya.Diskusi ada di sini https://redd.it/80kp1h
sumber
Ini mungkin berlebihan, tetapi antrian tugas yang didistribusikan Selery memiliki dukungan yang baik untuk batas waktu.
Secara khusus, Anda dapat menentukan batas waktu lunak yang hanya meningkatkan pengecualian dalam proses Anda (sehingga Anda dapat membersihkan) dan / atau batas waktu sulit yang menghentikan tugas ketika batas waktu telah terlampaui.
Di bawah penutup, ini menggunakan pendekatan sinyal yang sama seperti yang dirujuk di pos "sebelum" Anda, tetapi dengan cara yang lebih dapat digunakan dan dikelola. Dan jika daftar situs web yang Anda pantau panjang, Anda mungkin mendapat manfaat dari fitur utamanya - semua jenis cara untuk mengelola pelaksanaan sejumlah besar tugas.
sumber
python-requests
tetapi denganhttplib
(digunakan oleh permintaan untuk Python 2.7). Paket melewati semua yang terkaittimeout
langsung ke httplib. Saya pikir tidak ada yang bisa diperbaiki dalam permintaan karena prosesnya dapat bertahan lama di httplib.Saya percaya Anda dapat menggunakan
multiprocessing
dan tidak bergantung pada paket pihak ke-3:Timeout diteruskan ke
kwargs
adalah batas waktu untuk mendapatkan setiap respon dari server, argumentimeout
adalah batas waktu untuk mendapatkan lengkap respon.sumber
batas waktu = (batas waktu koneksi, batas waktu baca data) atau memberikan argumen tunggal (batas waktu = 1)
sumber
kode ini berfungsi untuk socketError 11004 dan 10060 ......
sumber
Meskipun ada pertanyaan tentang permintaan, saya menemukan ini sangat mudah dilakukan dengan pycurl CURLOPT_TIMEOUT atau CURLOPT_TIMEOUT_MS.
Tidak perlu threading atau pensinyalan:
sumber
Jika Anda menggunakan opsi,
stream=True
Anda bisa melakukan ini:Solusinya tidak perlu sinyal atau multi-pemrosesan.
sumber
Hanya satu solusi lain (dapatkan dari http://docs.python-requests.org/en/master/user/advanced/#streaming-uploads )
Sebelum mengunggah, Anda dapat mengetahui ukuran konten:
Namun hati-hati, pengirim dapat menetapkan nilai yang salah di bidang respons 'panjang konten'.
sumber
Jika itu yang terjadi, buat utas pengawas yang mengacaukan keadaan internal permintaan setelah 10 detik, misalnya:
Perhatikan bahwa tergantung pada pustaka sistem Anda mungkin tidak dapat menetapkan batas waktu pada resolusi DNS.
sumber
Yah, saya mencoba banyak solusi pada halaman ini dan masih menghadapi ketidakstabilan, hang acak, kinerja koneksi yang buruk.
Saya sekarang menggunakan Curl dan saya sangat senang dengan fungsionalitas "waktu max" dan tentang kinerja global, bahkan dengan implementasi yang buruk:
Di sini, saya mendefinisikan parameter waktu maks 6 detik, melibatkan koneksi dan waktu transfer.
Saya yakin Curl memiliki ikatan python yang bagus, jika Anda lebih suka tetap menggunakan sintaks pythonic :)
sumber
Ada paket yang disebut timeout-decorator yang dapat Anda gunakan untuk mematikan fungsi python.
Ia menggunakan pendekatan sinyal yang disarankan beberapa jawaban di sini. Sebagai alternatif, Anda dapat memerintahkannya untuk menggunakan multi-pemrosesan alih-alih sinyal (misalnya jika Anda berada di lingkungan multi-utas).
sumber
Saya menggunakan permintaan 2.2.1 dan eventlet tidak berhasil untuk saya. Alih-alih, saya bisa menggunakan timeout gevent karena gevent digunakan dalam layanan saya untuk gunicorn.
Harap dicatat bahwa gevent.timeout.Timeout tidak ditangkap oleh penanganan Pengecualian umum. Jadi baik secara eksplisit menangkap
gevent.timeout.Timeout
atau meneruskan dalam pengecualian berbeda untuk digunakan seperti:with gevent.Timeout(5, requests.exceptions.Timeout):
meskipun tidak ada pesan yang dilewatkan ketika pengecualian ini dimunculkan.sumber
Saya datang dengan solusi yang lebih langsung yang diakui jelek tetapi memperbaiki masalah sebenarnya. Bunyinya agak seperti ini:
Anda dapat membaca penjelasan lengkapnya di sini
sumber
timeout
parameterrequests.get()
tanpa penyelesaian yang buruk 2- meskipun keduanya tidak akan membatasi batas waktu total tidak sepertieventlet.Timeout(10)