Используя пользовательскую функцию (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
size - len(names)
.
Будущие объекты дают вам лучший контроль над полученными ответами, например, если он был выполнен правильно или возникло исключение или тайм-аут et c. Подробнее про здесь
Вы не рискуете столкнуться с проблемами, связанными с большим количеством потоков (решение 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
. Его длина должна совпадать с количеством создаваемых потоков.
Этот код не будет работать, если вам нужно вызвать другой параметр, например необязательный