Вы можете использовать несколько потоков, чтобы распараллелить выборку. В этой статье представлен один из возможных способов сделать это, используя класс ThreadPoolExecutor
из модуля concurrent.futures .
Похоже, @gold_cy опубликовал практически то же самое Ответь пока я работал над этим, но для потомков вот мой пример. Я взял ваш код и изменил его, чтобы использовать исполнителя, и немного изменил его для запуска локально, несмотря на отсутствие удобного доступа к списку JSON URL.
Я использую список из 100 URL-адресов, и требуется около 125 секунд для последовательного получения списка, и около 27 секунд с использованием 10 рабочих. Я добавил тайм-аут для запросов, чтобы не допустить, чтобы сломанные серверы удерживали все, и добавил код для обработки ответов об ошибках.
import json
import pandas
import requests
import time
from concurrent.futures import ThreadPoolExecutor
def fetch_url(data):
index, url = data
print('fetching', url)
try:
r = requests.get(url, timeout=10)
except requests.exceptions.ConnectTimeout:
return
if r.status_code != 200:
return
filename = f'./data/{index}.json'
with open(filename, 'w') as f:
json.dump(r.text, f)
pd_url = pandas.read_csv('urls.csv')
start = time.time()
with ThreadPoolExecutor(max_workers=10) as runner:
for _ in runner.map(fetch_url, enumerate(pd_url['URL'])):
pass
runner.shutdown()
time_taken = time.time()-start
print('time taken:', time_taken)
Кроме того, каковы возможные факторы, которые задерживают ответы?
Время ответа удаленного сервера станет основным узким местом.