Взаимодействие с сетью
Работа с зеркалами
Для начала стоит упомянуть что сайт rezka.ag имеет множество постоянно меняющихся зеркал, с которыми библиотека так же умеет работать:
from HDrezka import HDrezka
# Установив зеркало, все запросы будут направляться через него
main_page = HDrezka(mirror="https://hdrezka8benxe.org").get()
print(main_page.url)
# >>> https://hdrezka8benxe.org/
# Однако любые запросы сделанные напрямую с использованием url не будут использовать зеркало
main_page = HDrezka().get(url="https://rezka.ag/")
print(main_page.url)
# >>> https://rezka.ag/
Примечание
После установки зеркала, все запросы отправленные с помощью библиотеки будут отправляться на данное зеркало до тех пор, пока программа не прекратит свою работу или зеркало не будет изменено повторно.
Connector и работа с ним
Механизм который позволяет работать с зеркалами(и не только) называется коннектором. Connector - это фундаментальный объект для работы с сетью в данной библиотеке. Именно через него будут проходить все ваши интернет запросы, а понимание принципов его работы позволит вам работать с библиотекой более гибко. Библиотека предоставляет собственный RequestConnector, что установлен по умолчанию:
from HDrezka.connector import RequestConnector
my_connector = RequestConnector()
print(my_connector.user_agent) # Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/119.0
response = my_connector.get(url="https://httpstat.us/200")
print(response.status_code)
# >>> 200
print(response.text)
# >>> 200 OK
Но сам по себе коннектор не особо полезен, ведь по большей части он реализует те же возможности что доступны напрямую из requests. Однако, если передать коннектор в NetworkClient, в качестве аргумента, тогда все запросы из библиотеки будут проходить через данный коннектор. Это происходит за счёт того что класс NetworkClient является одиночкой и любые изменения в любом из его экземпляров затронут и все остальные.
from HDrezka import HDrezka
from HDrezka.connector import RequestConnector, NetworkClient
client = NetworkClient(connector=RequestConnector)
# Обратите внимание на то что NetworkClient позволяет напрямую обращаться к RequestConnector
client.domain = "hdrezka8benxe.org" # устанавливаем домен зеркала
main_page = HDrezka().get()
print(main_page.url)
# >>> https://hdrezka8benxe.org/
# Всё ещё любые запросы сделанные напрямую с использованием url не будут использовать зеркало
main_page = HDrezka().get(url="https://rezka.ag/")
print(main_page.url)
# >>> https://rezka.ag/
Создание собственных коннекторов
Базовый RequestConnector хоть и позволяет работать с сетью на базовом уровне, но всё же имеет довольно примитивную реализацию. Поэтому вполне возможно что вам однажды станет его недостаточно, на этот случай предусмотрено создание собственных коннекторов. Как и RequestConnector который является наследником базового абстрактного класса Connector любой ваш собственный коннектор должен быть его потомком, а так же согласно базовой структуре должен иметь методы get и post. В качестве примера давайте создадим коннектор с возможностью логирования всех проходящих через него запросов:
import logging
import sys
from typing import Union, Dict, Any
import requests
from HDrezka import HDrezka
from HDrezka.connector import NetworkClient, Connector
logging.basicConfig(level=logging.INFO, stream=sys.stdout, format="%(asctime)s | %(levelname)-8s | %(message)s")
class MyConnector(Connector):
def get(self, url: Union[str, bytes], **kwargs: Dict[str, Any]):
logging.info("GET request to url = %s with kwargs = %s", url, kwargs)
return requests.get(url, headers=self.get_headers(url), proxies=self.proxies, **kwargs, timeout=15)
def post(self, url: Union[str, bytes], **kwargs: Dict[str, Any]):
logging.info("POST request to url = %s with kwargs = %s", url, kwargs)
return requests.post(url, headers=self.get_headers(url), proxies=self.proxies, **kwargs, timeout=15)
NetworkClient(connector=MyConnector)
hdrezka = HDrezka()
collections = hdrezka.collections().get()
list_posters = collections[0].get()
print(list_posters)
# >>> 2024-04-01 18:21:55,46 | INFO | GET request to url = https://rezka.ag/collections/ with kwargs = {}
# >>> 2024-04-01 18:21:55,97 | INFO | GET request to url = https://rezka.ag/collections/3482-serialy-okko/ wit...
# >>> [Poster("Михаил Горшенёв. Легенда о Короле и Шуте"), Poster("Ласт квест"), Poster("Волшебный участок"), Poste...
Как видим, теперь все запросы, создаваемые библиотекой, проходят через наш коннектор и логируются. Использование данного коннектора ограничивается исключительно вашими потребностями. В качестве дополнительной идеи можно добавить кэширование запросов в базу данных (БД) и при повторении запросов извлекать их оттуда, вместо создания нового запроса к серверу.