С помощью пользовательской функции (request_post
) вы можете делать практически все.
import concurrent
import requests
def request_post(url, data):
return requests.post(url, data=data)
with concurrent.futures.ThreadPoolExecutor() as executor: # optimally defined number of threads
res = [executor.submit(request_post, url, data) for data in names]
concurrent.futures.wait(res)
res
будет список request.Response
для каждого запроса, сделанного в Future
экземплярах. . Чтобы получить доступ к request.Response
, вам нужно использовать res[index].result()
, где index
размер равен len(names)
.
Будущие объекты дают вам лучший контроль над полученными ответами, например, правильно ли они завершились, было ли исключение или тайм-аут и т. д. Подробнее о здесь
Вы не рискуете столкнуться с проблемами, связанными с большим количеством потоков (решение 2).
Решение 2. multiprocessing.dummy.Pool
и создание одного потока для каждого запроса
Может быть полезно, если вы не запрашиваете много страниц, а также если время отклика довольно медленное.
from multiprocessing.dummy import Pool as ThreadPool
import itertools
import requests
with ThreadPool(len(names)) as pool: # creates a Pool of 3 threads
res = pool.starmap(requests.post(itertools.repeat(url),names))
pool.starmap
— используется для передачи (map) нескольких аргументов в одну функцию (requests.post
), которая будет вызываться списком потоков (ThreadPool
). Он вернет список request.Response
для каждого сделанного запроса.
intertools.repeat(url)
необходимо, чтобы первый аргумент повторялся в том же количестве создаваемых потоков.
names
— это второй аргумент requests.post
, поэтому он будет работать без необходимости явно использовать необязательный параметр data
. Его len должен совпадать с количеством создаваемых потоков.
Этот код не будет работать, если вам нужно вызвать другой параметр, например необязательный
person
eusoubrasileiro
schedule
25.05.2020