Python-Requests: warten Sie nicht auf die Anforderung zu beenden
In der Bash ist es möglich, einen Befehl auszuführen, der im hintergrund durch Anhängen &
. Wie kann ich es in Python?
while True:
data = raw_input('Enter something: ')
requests.post(url, data=data) # Don't wait for it to finish.
print('Sending POST request...') # This should appear immediately.
- Im Gegensatz zu CPU-bound-concurrency-Probleme in Python, das könnte eventuell gelöst werden, mit einem separaten thread, oder die Verwendung von
multiprocessing.dummy
für einen thread-pool.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Benutze ich
multiprocessing.dummy.Pool
. Ich erstelle ein singleton thread-pool auf der Modul-Ebene, und verwenden Sie dannpool.apply_async(requests.get, [params])
starten Sie die Aufgabe.Dieser Befehl gibt mir eine Zukunft, die ich hinzufügen können, um eine Liste mit anderen futures auf unbestimmte Zeit, bis ich würde gerne erfassen alle oder einige der Ergebnisse.
multiprocessing.dummy.Pool
ist, gegen alle Logik und Vernunft, eine THREAD-pool-und nicht ein Prozess-pool.Beispiel (funktioniert in Python 2 und 3, solange Anforderungen installiert ist):
Die Anfragen werden parallel ausgeführt, so laufen alle zehn von diesen Anforderungen sollte nicht länger als der längste. Diese Strategie wird nur ein CPU-core, aber das sollte kein Problem sein, weil fast alle die Zeit des Wartens auf I/O.
requests.post(*args, **kwargs)
Sie verwendenfutures.append(pool.apply_async(requests.post, args, kwargs))
dann können Sie Ihr Modell und dem auslösen des requests one at a time, aber Sie müssen nicht warten, bis Sie abgeschlossen ist. Die Anfragen werden sofort ausgeführt, wenn apply_async getroffen wird, werden Sie nicht warten, bis Sie sammeln die futures.requests.post(url, data=data
) istpool.apply_async(s.post, [url, data, data])
. Nun, warum bekomme ich einen "NameError: name 'Daten' ist nicht definiert" - Fehler, wenn ich den Namen ändern, derdata
variable? Man würde denken, dass es ja egal...pool.apply_async(requests.post, [url], {'data': data})
. Die Funktion, die Unterschrift ist im wesentlichen (function_to_run, list_of_positional_args, dict_of_kwargs)..status_code
aus eine Anfrage gesendet mitr = pool.apply_async(...)
ohne es in eine Liste?r.status_code
gibt einAttributeError
.r
ist nicht ein Antwort-Objekt, es ist eine Zukunft, für ein response-Objekt. Erhalten Sie die wirkliche Reaktion mitr.get()
-- erzeugt ein response-Objekt, das ist das gleiche wie jeder andere. Wenn Sie wollen nur den status-code, den Sie tun konnter.get().status_code
(beachten Sie, dass, wenn der Antrag führte zu einer Ausnahme, die Ausnahme wird ausgelöst, wenn Sie anrufenget()
). Sie können auchresponse = r.get()
und normal fortfahren. Wenn Sier.get()
vor der eigentlichen asynchrone Anforderung abgeschlossen ist, dann werden Sie automatisch warten Sie, bis die Anforderung abgeschlossen ist, bevor Sie fortfahren.Hier ist ein hacky Weg, es zu tun:
Elegante Lösung aus Andrew Gorcester. Außerdem, ohne den Einsatz von futures, ist es möglich, die
callback
underror_callback
Attribute (siehedoc) zur Durchführung von asynchronen Verarbeitung:
Entsprechend der doc, sollten Sie in einer anderen Bibliothek :
csrf = s.cookies['csrftoken']
.Wenn Sie den code schreiben, der ausgeführt werden separat in einem separaten python-Programm, hier ist eine mögliche Lösung, basierend auf der Vergabe eines unterauftrags.
Sonst können Sie nützlich finden diese Frage und Verwandte Antwort: der trick ist, verwenden Sie die threading-Bibliothek starten Sie einen separaten thread, der ausgeführt wird, die getrennt Aufgabe.
Einen VORBEHALT mit beiden Ansatz könnte sein, die Anzahl der Elemente (also der Anzahl der threads), die Sie verwalten. Wenn die
item
s inparent
sind zu viele, können Sie erwägen, die Eindämmung jeder charge der Gegenstände, bis mindestens einige threads beendet haben, aber ich denke, diese Art von management ist nicht trivial.Weitere anspruchsvolle Ansatz, den Sie verwenden können, ein Schauspieler, der Ansatz, ich habe nicht verwendet diese Bibliothek mir, aber ich denke, es könnte helfen in diesem Fall.