June 21, 2022

HTTP запросы для новичка [py]

Как устроена эта статья:

> Введение

> Что можно юзать?

  1. Requests
  2. Grequests
  3. Httpx
  4. Aiohttp

> Бенчмарки


Введение

HTTP — это протокол, позволяющий получать различные ресурсы, например HTML-документы. Протокол HTTP лежит в основе обмена данными в Интернете, другими словами каждое ваше действия которую вы делаете в браузере (просмотр видео на youtube, регистрация на сайте) все это HTTP запросы.

Ниже будут рассматриваться несколько библиотек, которые помогут выполнять HTTP запросы через код.

Что можно юзать?


Requests

pip install requests

requests одна из самых простых библиотек которая позволит отправлять HTTP-запросы с помощью Python.

Простои пример

import requests
r = requests.get("https://example.com")
print(r)

Обычно все новички начинают с этой библиотекой, потом переходят на другие более оптимальные.

Плюсы:
> просто и понятно (освоить можно за несколько часов)
> много гайдов на ютубе/инете
> подходит для любых задач

минусы:
> маленькая скорость


Grequests

pip install grequests

grequests позволяет использовать запросы с Gevent для легкого выполнения асинхронных HTTP-запросов. Грубо говоря, обычные реквесты с асинком под капоты.

Либа ещё сырая и не видел много где оно применяется, подходит если вам надо сделать много простых запросов на один сайт.

Простои пример

import grequests
rs = (grequests.get("https://example.com") for _ in range(100))
print(grequests.map(rs))

Сравнение с обычными реквестами

import grequests
import requests
from time import perf_counter

def greq(count: int):
    start = perf_counter()    
    rs = (grequests.get("https://example.com") for _ in range(count))    
    grequests.map(rs)    
    print(f"grequests executed in {perf_counter() - start} seconds...")
    
def req(count: int):
    start = perf_counter()    
    for _ in range(count):        
        requests.get('https://example.com')    
    print(f"requests executed in {perf_counter() - start} seconds...")
    
greq(100)
req(100)

С это задачи requests справился за 49.19 секунд, в то время как grequests за 2.32 секунд.

плюсы:
> быстрая скорость (по сравнению с обычными реквестами)

минусы:
> либа ещё сырая
> гайдов поменьше
> менее удобное чем те же реквесты


Httpx

pip install httpx

httpx - это полнофункциональный HTTP-клиент для Python 3, который предоставляет API-интерфейсы синхронного кода так и асинхронного.

синхронная часть httpx очень схожа с теми же реквестами, отличается только использования сессии, в httpx она работает немного иначе.

Простои пример

import httpx

with httpx.Client() as client:
    r = client.get("https://example.com")
    print(r)

Если в реквестах сессию можно инициировать и потом использовать, то в httpx можно передавать клиент в другие функций при это все куки, и хедеры будут сохранены.

import httpx


def test_func(client: httpx.Client):
    client.get("https://youtube.com")
    

def main():
    with httpx.Client() as client:
        client.get("https://example.com")        
        print(client.cookies.jar)        
        test_func(client)        
        print(client.cookies.jar)


main()

Плюсы:
> поддержка синк кода так и асинк
> быстрее чем реквесты и grequests
> дока удобная, все в одном месте

минусы:
> медленнее чем aiohttp


Aiohttp

pip install aiohttp

aiohttp - HTTP-клиент/сервер. По сути, это позволяет вам писать асинхронные клиенты и серверы. Пакет aio http также поддерживает серверные Server WebSockets и Client WebSockets

простой пример

import aiohttp
import asyncio


async def main():
    async with aiohttp.ClientSession() as client:
        r = await client.get("https://example.com")        
        print(r.status)
        
        
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
asyncio.run(main())

плюсы:
> самая быстрая либа на данный момент
> либа не новая, гайдов много

минусы:
> неудобно работать с куками
> поддержка только асинк кода


Бенчмарки

+--------------------------------------+
|  100 requests on https://example.com |
+----------------------+---------------+
| requests             | 48.88 seconds |
+----------------------+---------------+
| requests (session)   | 12.34 seconds |
+----------------------+---------------+
| sync httpx (client)  | 12.39 seconds |
+----------------------+---------------+
| async httpx (client) | 2.20 seconds  |
+----------------------+---------------+
| aiohttp              | 0.81 seconds  |
+----------------------+---------------+
| grequests            | 2.11 seconds  |
+----------------------+---------------+

код который был использован для теста: github