Как ускорить отправку 3х GET-запросов
После прогона всех элементов, результаты будут в results :
import requests from multiprocessing.dummy import Pool as ThreadPool urls = [ 'http://mysite.com/check.php?userid=666&userage=18', 'http://mysite.com/check.php?userid=777&userage=22', 'http://mysite.com/check.php?userid=888&userage=26', ] pool = ThreadPool() results = pool.map(requests.get, urls) print(results)
PS. Хоть multiprocessing и относится к обработке в процессах, его модуль multiprocessing.dummy работает через потоки.
PPS. В results будет храниться результат выполнения requests.get(url) , поэтому можно после обработать, например:
for x in results: print(x, len(x.content), x.content)
Отслеживать
ответ дан 5 мая 2018 в 14:31
76.7k 6 6 золотых знаков 54 54 серебряных знака 121 121 бронзовый знак
после некоторого количества циклов, вылезла ошибка Runtime error: cant start new thread, как я понимаю из за того, что потоки не закрывались
5 мая 2018 в 17:40
@babyborn, какая ошибка?
5 мая 2018 в 17:40
обновил коммент
5 мая 2018 в 17:46
а какой размер у urls? Только что создавал 1 000 000 элементов (без запроса по сети, просто len ) и нормально
5 мая 2018 в 17:49
в данный момент 20. в threading была такая фишка как join, тут есть что то подобное?
5 мая 2018 в 17:54
Один из вариантов это использование asyncio.
import asyncio import requests async def main(): loop = asyncio.get_event_loop() future1 = loop.run_in_executor(None, requests.get, 'http://mysite.com/check.php?userid=666&userage=18') future2 = loop.run_in_executor(None, requests.get, 'http://mysite.com/check.php?userid=777&userage=22') future3 = loop.run_in_executor(None, requests.get, 'http://mysite.com/check.php?userid=888&userage=26') response1 = await future1 response2 = await future2 response3 = await future3 print(response1.text) print(response2.text) print(response3.text) loop = asyncio.get_event_loop() loop.run_until_complete(main())
Подробно описано вот здесь
UPDATED. Если нужно задать заголовки, то можно использовать functools.partial :
future1 = loop.run_in_executor(None, functools.partial(requests.get, 'http://httpbin.org/get', headers=))
Или же вариант с aiohttp:
import asyncio from aiohttp import ClientSession async def fetch(url, session): async with session.get(url, headers=) as response: return await response.read() async def run(): urls = ( 'http://mysite.com/check.php?userid=666&userage=18', 'http://mysite.com/check.php?userid=777&userage=22', 'http://mysite.com/check.php?userid=888&userage=26', ) async with ClientSession() as session: tasks = [ asyncio.ensure_future(fetch(url, session)) for url in urls ] responses = await asyncio.gather(*tasks) print(responses) loop = asyncio.get_event_loop() future = asyncio.ensure_future(run()) loop.run_until_complete(future)
Кроме того можно рассмотреть кэширование результатов запроса (если контекст задачи позволяет) например при помощи redis (https://github.com/vivekn/redis-simple-cache как вариант).
from redis_cache import cache_it, SimpleCache my_cache = SimpleCache(expire=60) @cache_it(cache=my_cache) def get_data(url): .
Ускорить GET запрос
Ускорить запрос
Есть запрос EXPLAIN (ANALYZE, BUFFERS) SELECT "Event", .
Ускорить запрос
Здравствуйте! Имеем таблицу в ней 7 млн. строк , делаю простой запрос: SELECT * FROM.
Как ускорить запрос?
Очень медленно выполняется запрос(с индексами), около 20 секунд для 2.7 млн. строк в таблице;.
Ускорить простой запрос
Ускорить простой запрос нужно проверить входят ли ид. записей из массива в таблицу SELECT.
Как ускорить запрос?
SELECT p.id_patient FROM patients p LEFT JOIN receptions r ON (p.id_patient = r.id_patient) .
![]()
2679 / 1585 / 512
Регистрация: 21.02.2017
Сообщений: 4,205
Записей в блоге: 1
А для чего тебе это ускорять?
Добавлено через 1 минуту
Максимум можно в другой поток пропихнуть.
Автоматизируй это!
![]()
7054 / 4559 / 1207
Регистрация: 30.03.2015
Сообщений: 13,132
Записей в блоге: 29
Рэйн, а какой урл что там текст так долго обрабатывается?
как вариант попробуй получать контент
![]()
5416 / 3840 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1
Сообщение от Рэйн 
Можно ли как-то это ускорить?
Можно ли добраться на одном и том же транспортном средстве из Москвы в Пекин быстрее, чем из из Москвы в Питер?
Сообщение от Рэйн 
И теперь код выполняется 20-30 секунд
Тебя это действительно удивляет?
Файл размером в 10-100mb не может загрузиться также быстро как и файл размером в 1kb.
Добавлено через 2 минуты
P.S. Если по video_url загружается контент видеофайла, то зачем там .text, когда нужны байты, то есть .content?
P.P.S. В первом примере ты вообще ничего не загружаешь. Ты просто делаешь запрос и получаешь заголовки ответа. Тела файла там вообще еще нет.
![]()
2679 / 1585 / 512
Регистрация: 21.02.2017
Сообщений: 4,205
Записей в блоге: 1
Сообщение от Garry Galler 
Можно ли добраться на одном и том же транспортном средстве из Москвы в Пекин быстрее, чем из из Москвы в Питер?
Можно, по ветру или против. ¯\_(ツ)_/¯
Регистрация: 17.03.2019
Сообщений: 47
Мне нужно написать скрипт для скачивания тикток видео. Вот весь код
from TikTokApi import TikTokApi
import requests
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
api = TikTokApi() id = 6842995359594188038 video_info = api.getTikTokById(id) print(1) video_url = video_info["itemInfo"]["itemStruct"]["video"]["downloadAddr"] print(2) headers = {"User-Agent": "okhttp"} print(video_url) video_data = requests.get(video_url) print('2.1') video_data = video_data.text #ускорить print(3) pos = video_data.find("vid:") print(4) video_url_no_wm = "https://api2-16-h2.musical.ly/aweme/v1/play/?video_id= \ ">&vr_type=0&is_play_url=1&source=PackSourceEnum_PUBLISH&media_type=4" \ .format(video_data[pos+4:pos+36]) video_data_no_wm = requests.get(video_url_no_wm, params=None, headers=headers) print(5) with open("download_videos/" + '123.mp4', 'wb') as out: out.write(video_data_no_wm.content) print(video_url_no_wm)
Дольше всего выполняется это:
video_data = video_data.text #ускорить
Как ускорить большое количество get запросов?
Таблица из двух стобцов id и url, 5 миллионов записей
Требуется дернуть все урлы get запросом и получить айдишники урлов у которых статус не 200.
Если делать это последовательно, то уходит очень много времени.(особенно если учесть то что некоторые отдают 504)
Как ускорить поиск?
- Вопрос задан более трёх лет назад
- 824 просмотра
1 комментарий
Простой 1 комментарий

Модератор @TosterModerator
Исправьте вопрос так, чтобы он описывал конкретную проблему с достаточной детализацией для определения адекватного ответа.
Решения вопроса 1
Основное происходит в строке с pool.map
import urllib2 from multiprocessing.dummy import Pool as ThreadPool urls = [ 'http://www.python.org', 'http://www.python.org/about/', 'http://www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html', 'http://www.python.org/doc/', 'http://www.python.org/download/', 'http://www.python.org/getit/', 'http://www.python.org/community/', 'https://wiki.python.org/moin/', 'http://planet.python.org/', 'https://wiki.python.org/moin/LocalUserGroups', 'http://www.python.org/psf/', 'http://docs.python.org/devguide/', 'http://www.python.org/community/awards/' # etc.. ] # Make the Pool of workers pool = ThreadPool(4) # Open the urls in their own threads # and return the results results = pool.map(urllib2.urlopen, urls) #close the pool and wait for the work to finish pool.close() pool.join()
Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать
Ответы на вопрос 5

Python developer
Если идут несколько запросов к одному серверу, то стоит использовать сессию что не открывать каждый раз новый коннекшен. У requests к примеру есть requests.session.
Ответ написан более трёх лет назад
Комментировать
Нравится 2 Комментировать
Олег @OlegPyatakov
pyatakov.com
Основная потеря времени — ожидание ответов от удаленных серверов.
- Работать в несколько потоков
- Работать в несколько процессов
- Работать через асинхронные запросы
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать

Быстрее чем может отдать сервер — никак
Используйте scrapy — там есть весь требуемый функционал
Если сайт донор на шареде, то его еще может прибанить хостер
Потому не делайте на него 100RPS
Ответ написан более трёх лет назад
Нравится 1 6 комментариев
Проблема scrapy только в том, что это утилита, а не библиотека/фреймворк.
Прикрутить его к своему коду относительно заморочно. Но возможно.

Максим Васильев, к какому конкретно коду?
В чем заморочка?
Вот тут есть решения:
https://doc.scrapy.org/en/latest/topics/practices.html

sim3x, вы с кем разговариваете? и о чём?

Максим Васильев, у меня такой же вопрос к вам

Solution Architect, AWS Certified, Serverless
Как на счёт распараллелить задачи с помощью воркеров ? У меня всегда на этот случай есть message broker. Я просто накидывают туда задачи и в зависимости от числа задач ставлю больше или меньше воркеров. Только есть проблема что если ресурс один или не большое колличество то вас могут забанить
Многопоточный парсинг на Python

В этой статье я расскажу, как значительно ускорить парсинг сайта. Те, кто изучил парсинг и начал применять его на практике приходят к такому моменту как ожидание окончания работы парсера, в особенности, когда объем данных высок. На скорость работы влияет множество параметров, один из них — это время ответа сервера, т.к. серверу нужно время чтобы обработать информацию.
В статье я опишу один из способов борьбы с этой проблемой.
Использоваться будет библиотека «concurrent.futures». Использовать «concurrent» нужно умеренно, не стоит устраивать «DDoS» атаку на сайт.
Для создания многопотока ничего мудрёного делать не придётся, код очень прост и понятен. После установки импортируем библиотеки. Добавлены 2 дополнительные библиотеки, это «tqdm» индикатор процесса и «pandas» для создания датафрейма.
import requests import pandas as pd from tqdm import tqdm import concurrent.futures
Прописываем «headers» в request запросы, создаем сессию, объявляем функцию отправки запросов
headers = < 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_1_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36' >TIMEOUT = 10 session = requests.Session() session.headers = headers def load_url(url): answer = requests.get(url, headers=headers, timeout=TIMEOUT) return [url, answer.text]
Создаем датафрейм со списком «url» из файла «test.xlsx». Для тестирования берем только первые 2000 записей
df = pd.read_excel('test.xlsx') df.head()
| Index | source.objectHrefTerm |
| 0 | https://test.ru/PurchaseView/43/0/0/705675 |
| 1 | https://test.ru/PurchaseView/30/0/0/705663 |
| 2 | https://test.ru/PurchaseView/43/0/0/705661 |
| 3 | https://test.ru/PurchaseView/30/0/0/705653 |
| 4 | https://test.ru/PurchaseView/20/0/0/705300 |
urls = list(df['source.objectHrefTerm'])[:2000]
Вначале протестируем время выгрузки одним потоком
out = [] for url in tqdm(urls): out.append(load_url(url))

Прогресс-бар показывает скорость выполнения — 2 минуты и 21 секунду. Среднее количество запросов в секунду — 14.15.
Теперь сделаем те же 2000 запросов, используя concurrent.futures и 2 потока. Изменяется только параметр CONNECTIONS
out = [] CONNECTIONS = 2 with concurrent.futures.ThreadPoolExecutor(max_workers=CONNECTIONS) as executor: future_to_url = (executor.submit(load_url, url) for url in urls) for future in tqdm(concurrent.futures.as_completed(future_to_url), total=len(urls)): try: data = future.result() except Exception as exc: data = str(type(exc)) finally: out.append(data)

Прогресс-бар показал скорость выполнения 1 минута и 16 секунд. В среднем 26.06 запроса в секунду.
Наблюдается уже значительное увеличение скорости. Попробуем использовать 5 потоков.
out = [] CONNECTIONS = 5

Скорость парсера увеличилась почти в 5 раз.
При использовании большего количества потоков не на все запросы приходили ответы либо на время блокировался ip адрес.
Многопоточный парсинг позволяет нам выполнять работу быстрее, в нашем случае ускорение работы достигло 4,85 раз, что дает существенную экономию времени в больших пулах запросов.